单例模式

来源:互联网 发布:里约奥运会数据库 编辑:程序博客网 时间:2024/05/10 05:02

C++中一共有23中设计模式

设计模式:
设计模式代表了最佳实践,是软件开发过程中面临一般问题的解决方案;
设计模式是一套被反复使用,经过分类,代码设计总结的经验。

设计模式的一些基本原则:
一、单一职责原则

  1. 一个类只有一个职责,不应该既做这又做那,好处是:
  2. 降低了类的复杂性。
  3. 提高了代码的可读性,可维护性
  4. 降低了因变更带来的风险。

二、里氏替换原则

  1. 一个子类必须实现类的所有方法。
  2. 一个子类可以拥有父类没有的方法
  3. 在所有需要父类的地方都可以用子类对象的替换而不出现问题。

三、依赖倒置原则

  1. 高层模块不应该依赖底层模块
  2. 抽象不应该依赖于细节
  3. 实现应该依赖于抽象
  4. 面向接口编程

四、接口隔离原则。

  1. 一个类可以有多个方法,但是如果打算向外部提供部分方法,则把这些方法实现为接口,
    返回接口类型。

五、迪米特法则

  1. 最少知识法则
  2. 只与你直接的朋友通信
  3. 一个类不应该与过多的类发生联系
  4. 如果一个类需要调用第三个类的方法,则可以加入中间者,转发调用这个方法。

六、开关原则

  1. 最重要的一个核心原则
  2. 一个软件实体应该对扩展开放,对修改封闭

七、组合优于继承
八、把变与不变的事物分开

设计模式分类:
一、创建型:

1. 工厂方法设计模式(Factory Method)2. 抽象工厂模式(Abstract Factory)3. 创建者模式(Builder)4. 原型模式(Prototype)5. 单例模式(Sigleton)

二、结构性

1. 外观模式(Facade)2. 适配器模式(Adapter)3. 代理模式(Proxy)4. 装饰模式(Decorator)5. 桥接模式(Bridge)6. 组合模式(Composite)7. 享元模式(Flyweight)

三、行为模式

1. 模板方法模式(Template Method)2. 观察者模式(Observer)3. 状态模式(State)4. 策略模式(Strategy)5. 职责链模式(Chain of Responsiblity)6. 命令模式(Command)7. 访问者模式(Visitor)8. 中介者模式(Mediator)9. 备忘录模式(Memento)10. 迭代器模式(Iterator)11. 解释器模式(Interpreter)

下面我简单介绍几种模式:
抽象工厂模式:用工厂类的不同成员函数返回不同类型的对象。这样一来用户不必
记住各个类的名字。
bug:添加新类要修改原来的代码。

工厂方法:定义一个创建对象的接口,让子类决定实例化那一个类
这个模式是想突破抽象工厂修改源代码的问题,使用C++模板就可以轻松实现新类型的创建工作。

适配器模式:将一个类的接口转换为客户希望的另一个接口。

桥接模式:就抽象部分与实现部分分离,使它们都可以独立的变化。

迭代器模式:提供了一种方法去访问其它对象,解决了STL的封装性

本文我们主要研究一下单例模式:
单例模式也叫单件模式,Singleton是一个非常常用的设计模式,几乎大一点的程序都会用到它,
所以构建一个线程安全并且高效的Singleton很重要。

  1. 单例类保证全局只有一个唯一实例对象。
  2. 单例类提供获取这个唯一实例的接口。

第一种:懒汉模式

#pragma once#include<Windows.h>#include<mutex>class LazySingleton{public:    static LazySingleton* GetInstance() //获取唯一对象的实例接口    {        if (_inst == NULL) //使用双重检查提高效率,避免高并发下每次获取实例都加锁        {            std::lock_guard<std::mutex> lock(_mtx);            if (_inst == NULL)            {                //_inst=new LazySingleton   分为三部分 1.分配空间 2.调用构造函数3.赋值                LazySingleton* tmp = new LazySingleton();                MemoryBarrier();                _inst = tmp;            }        }        return _inst;    }    static void DelLazySingleton() //删除实例对象    {        std::lock_guard<std::mutex>lock(_mtx);        if (_inst)        {            delete _inst;            _inst = NULL;        }    }    void Print()    {        cout << "data=" << _data << endl;    }private:    LazySingleton()        :_data(0)    {}    LazySingleton(const LazySingleton&);    LazySingleton& operator=(const LazySingleton&);    int _data; //单例类里面的数据    static LazySingleton* _inst;     //指向实例的指针定义为静态私有,这样定义静态成员函数获取类的实例    static mutex _mtx;};LazySingleton* LazySingleton::_inst = NULL;mutex LazySingleton::_mtx;void TestLazySingleton(){    LazySingleton::GetInstance()->Print();    LazySingleton::DelLazySingleton();}

第二种:饿汉模式

#pragma onceclass HungrySinglenton{public:    static HungrySinglenton* GetInstance()    {        assert(_inst);        return _inst;    }    void Print()    {        cout << _data << endl;    }    static void DelHungry()    {        if (_inst)        {            delete _inst;            _inst = NULL;        }    }private:    HungrySinglenton()        :_data(0)    {}    HungrySinglenton(const HungrySinglenton&);    HungrySinglenton& operator=(const HungrySinglenton&);    int _data;    static HungrySinglenton* _inst;};HungrySinglenton* HungrySinglenton::_inst = new HungrySinglenton();void TestHungrySinglenton(){    HungrySinglenton::GetInstance()->Print();    HungrySinglenton::GetInstance()->Print();    HungrySinglenton::GetInstance()->Print();    HungrySinglenton::GetInstance()->Print();    HungrySinglenton::DelHungry();}

懒汉模式与饿汉模式的比较:

饿汉模式:一上来就创建实例对象,适用性受到限制,比如说动态库。
懒汉模式:虽然设计有点复杂,但是各种场景都适用。