设计模式 -- 学习笔记

设计模式

分类:

创建型设计模式:主要用于描述如何创建对象

结构型设计模式:主要用于描述如何实现类和对象的组合

行为型设计模式:主要用于描述类或对象怎样交互以及怎样分配职责

1.单例模式

  1. 设计需求:一个类只能创建一个对象

  2. 应用场景:全局唯一的资源,日志记录器、网页库、字典库

  3. 实现步骤:

    1. 构造函数设计为私有
    2. 设置静态的成员函数(getInstance)
    3. 静态数据成员_pInstance
    4. 将析构函数设置为私有(防止用户自己多次delete,造成double free)
    5. 为了释放堆空间,设计静态的析构函数(destroy)
    #include <stdlib.h>
    #include <pthread.h>
    #include <iostream>
    using std::cout;
    using std::endl;
    
    //单例模式自动释放4:pthread_once + atexit
    class Singleton
    {
    public:
        static Singleton *getInstance()
        {
            pthread_once(&_once, init);
            return _pInstance;
        }
        static void init()
        {
            _pInstance = new Singleton();
            atexit(destroy);
        }
        static void destroy()
        {
            if(_pInstance)
            {
                delete _pInstance;
                _pInstance = nullptr;
            }
        }
    
    private:
        Singleton()
        {
            cout << "Singleton() " << endl;
        }
        ~Singleton()
        {
            cout << "~Singleton() " << endl;
        }
    
    private:
        static Singleton *_pInstance;
        static pthread_once_t _once;
    };
    
    Singleton *Singleton::_pInstance = nullptr; 
    pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT;
    
  4. 自动释放

    1. 友元类形式进行设计:

      给实现单例模式的类添加一个友元类,该类析构函数实现调用单例模式的destory()函数或者直接delete。主函数中定义该友元类。

    2. 内部类+静态数据成员方式

      给实现单例模式的类定义个私有的内部类,该类析构函数实现调用单例模式的destory()函数或者直接delete,同时增加个该类的静态数据成员,在类外进行定义初始化。一定要设置成静态的,因为如果不设置成静态的,内部类的析构函数由外部类的析构函数负责调用,而外部类的析构函数不会随着程序结束自动调用,所以该情况下内部类的析构函数不会执行。

    3. atexit的方式

      用atexit()函数在new时注册destory()函数,当进程退出时会进行自动调用。

    4. pthread_once + atexit方式,函数原型:

      int pthread_once(pthread_once_t *once_control,void (*init_routine)(void));
      
      pthread_once_t once_control = PTHREAD_ONCE_INIT;
      

        以上三种方式为防止多线程时多次new只能使用饿汉模式,使用pthread_once(),保证了当once_control相同时,init_routine只调用一次,此时用饱汉、饿汉模式均可以。once_control为静态数据成员和init函数为静态成员函数,因为getInstance()函数为静态的,只能访问静态的数据成员和成员函数。

2.工厂模式

  1. 设计需求:封装对象创建时的不确定性

  2. 使用场景

    1. 简单对象不需要使用工厂模式;
    2. 复杂对象才需要使用工厂模式;
    3. 对于不确定的对象,可以使用工厂模式。
  3. 以图像对象的创建为例,UML如下:
    请添加图片描述

3.观察者模式

  1. 设计需求:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都得到通知并被自动更新。

  2. 以在医院病房里,门铃响后,护士和婴儿的反应作为例子,UML如下:
    请添加图片描述

  3. 对于观察者模式中的推模式和拉模式

    1. 推模式

      在observer的update()函数的参数中加上Status的引用,在调用notify()函数时通过参数的传递,将状态值传递给observer。

    2. 拉模式

      Oberver类中添加Subject的指针,当创建观察者时,就将Ring注册给观察者,当状态发生变化调用update()函数时,在update()内调用Subject的getStatus()就可以获取到状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值