• 23种设计模式之——单例模式


    单例模式也称为单件模式、单子模式。单例模式有许多种实现方法,甚至可以直接用一个全局变量做到这一点,但这样的代码显得很不优雅。《设计模式》一书中给出了一种很不错的实现。 

    定义:确保一个类只有一个实例,而且自行实例化,并提供一个访问它的全局访问点,该实例被所有程序模块共享。

    类型:创建类模式

    类图:

    单例模式应该是23种设计模式中最简单的一种模式了。它有以下几个要素:

    • 私有的构造方法
    • 指向自己实例的私有静态引用
    • 以自己实例为返回值的静态的公有的方法

            单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例。饿汉式单例在单例类被加载时候,就实例化一个对象交给自己的引用;而懒汉式在调用取得实例方法的时候才会实例化对象。代码如下:

    饿汉式单例

    class CSingleton { 
    public:
    static CSingleton* getInstance(){
    return m_pInstance;
    }
    private:
    CSingleton(){}
    static CSingleton* m_pInstance;
    };
    CSingleton* CSingleton::m_pInstance= new CSingleton;

    懒汉式单例: 

    class CSingleton { 
    public:
    static CSingleton* getInstance(){
    if(m_pInstance == NULL){
    m_pInstance = new CSingleton();
    }
    return m_pInstance;
    }
    private:
    CSingleton(){}
    static CSingleton* m_pInstance;
    };
    CSingleton* CSingleton::m_pInstance = NULL;

      单例模式需要注意的两个问题:

    1.懒汉式单例模式线程安全问题:

      遇到多线程问题时,假如现在有两个线程A和线程B,线程A执行到 this.singletonPattern = new SingletonPattern(),正在申请内存分配,可能需要0.001微秒,就在这0.001微秒之内,线程B执行到if(this.singletonPattern == null),你说这个时候这个判断条件是true还是false?是true,那然后呢?线程B也往下走,于是乎就在内存中就有两个SingletonPattern的实例了,看看是不是出问题了?所以,在编写懒汉式单例模式时,应注意线程安全问题,具体方法视个人习惯而定。

    2.资源回收:

      有经验的读者可能会问,m_pInstance指向的空间什么时候释放呢?我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。

      利用这个特征,我们可以在单例类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。如下面的代码中的CGarbo类(Garbo意为垃圾工人):

    class CGarbo {      
    public:
    ~CGarbo()
    {
    if (CSingleton::m_pInstance)
    delete CSingleton::m_pInstance;
    }
    };
    static CGarbo Garbo;

      

    单例模式的优点:

    • 在内存中只有一个对象,节省内存空间。
    • 避免频繁的创建销毁对象,可以提高性能。
    • 避免对共享资源的多重占用。
    • 可以全局访问。

    适用场景:由于单例模式的以上优点,所以是编程中用的比较多的一种设计模式。我总结了一下我所知道的适合使用单例模式的场景:

    • 需要频繁实例化然后销毁的对象。
    • 创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
    • 有状态的工具类对象。
    • 频繁访问数据库或文件的对象。
    • 以及其他我没用过的所有要求只有一个对象的场景。

      至此为止,不考虑线安全问题,完整的单例模式代码如下:

    饿汉式单例完整代码
    class CSingleton { 
    public:
    static CSingleton* getInstance(){
    return m_pInstance;
    }
    private:
    CSingleton(){}
    static CSingleton* m_pInstance;
    class CGarbo {
    public:
    ~CGarbo()
    {
    if (CSingleton::m_pInstance)
    delete CSingleton::m_pInstance;
    }
    };
    static CGarbo Garbo;
    };
    CSingleton* CSingleton::m_pInstance= new CSingleton;
    懒汉式单例完整代码 
    class CSingleton { 
    public:
    static CSingleton* getInstance(){
    if(m_pInstance == NULL){
    m_pInstance = new CSingleton();
    }
    return m_pInstance;
    }
    private:
    CSingleton(){}
    static CSingleton* m_pInstance;
    class CGarbo {
    public:
    ~CGarbo()
    {
    if (CSingleton::m_pInstance)
    delete CSingleton::m_pInstance;
    }
    };
    static CGarbo Garbo;
    };
    CSingleton* CSingleton::m_pInstance = NULL;
    
    
  • 相关阅读:
    jQuery序列化
    jQuery的ajax与django传参
    Django中的cookie与session操作
    Django文件上传
    Django表单的简单应用
    django加载模板文件
    django-admin.py创建项目失败解决方法
    django笔记
    unity创建xml与加载xml
    JavaScript相关
  • 原文地址:https://www.cnblogs.com/LemonTea2012/p/2421171.html
Copyright © 2020-2023  润新知