`

[创建型模式] head first 设计模式之单件模式(Singleton)

 
阅读更多
1 意图
  保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2 适用性
  在下面的情况下可以使用Singleton模式
  a)当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时;
  b)当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需要更改代码就能适用一个扩展的实例时;


3 优点
  a)对唯一实例的受控访问;
  因为Singleton类封装它的唯一实例,所以它可以严格的控制客户怎样以及何时访问它;

  b)缩小名空间
  Singleton模式是对全局变量的一种改进,它避免了那些存储唯一实例的全局变量名空间

  c)允许对操作和表示的精化;
  Singleton类可以有子类,而且这个扩展类的实例来配置一个应用时很容易的。你可以用你所需要的类的实例在运行时刻配置应用。

  d)允许可变数目的实例;
 
  e)比类操作更灵活;




标准的单例模式,仅适用于单线程
//////////////////////////////////////////////////////////////////////////
class ChocolateBoiler
{
private:
    ChocolateBoiler()
    {
        m_bEmpty = true;
        m_bBoiled = false;
    }

public:
    static ChocolateBoiler* getInstance()
    {
        if (m_pUniqueInstance == NULL)
        {
            //标准的单例模式,多线程下面有可能创建多个实例
            m_pUniqueInstance = new ChocolateBoiler();
        }

        return m_pUniqueInstance;
    }

    ~ChocolateBoiler()
    {
        if (m_pUniqueInstance != NULL)
        {
            delete m_pUniqueInstance;
        }
    }

    void fill()
    {
        if (isEmpty())
        {
            m_bEmpty = false;
            m_bBoiled = false;
            //在锅炉内填满巧克力和牛奶的混合物
        }

        if (m_bEmpty)
        {
            cout << "[ChocolateBoiler::fill] Empty\n";
        }
        else
        {
            cout << "[ChocolateBoiler::fill] Full\n";
        }

        if (m_bBoiled)
        {
            cout << "[ChocolateBoiler::fill] Boiled\n";
        }
        else
        {
            cout << "[ChocolateBoiler::fill] Not Boil\n";
        }
    }

    void drain()
    {
        if (!isEmpty() && isBoiled())
        {
            //排出煮沸的巧克力和牛奶
            m_bEmpty = true;
        }

        if (m_bEmpty)
        {
            cout << "[ChocolateBoiler::drain] Empty\n";
        }
        else
        {
            cout << "[ChocolateBoiler::drain] Full\n";
        }
    }

    void boil()
    {
        if (!isEmpty() && !isBoiled())
        {
            //将炉内物煮沸
            m_bBoiled = true;
        }

        if (m_bBoiled)
        {
            cout << "[ChocolateBoiler::boil] Boiled\n";
        }
        else
        {
            cout << "[ChocolateBoiler::boil] Not Boil\n";
        }
    }

    bool isEmpty()
    {
        return m_bEmpty;
    }

    bool isBoiled()
    {
        return m_bBoiled;
    }

private:
    bool m_bEmpty;
    bool m_bBoiled;
    static ChocolateBoiler* m_pUniqueInstance;
};

ChocolateBoiler* ChocolateBoiler::m_pUniqueInstance = 0;

class ChocolateBoilerTestDrive
{
public:
    void run()
    {
        ChocolateBoiler* pInstance = ChocolateBoiler::getInstance();
        pInstance->fill();
        pInstance->boil();
        pInstance->drain();

        ChocolateBoiler* pInstance2 = ChocolateBoiler::getInstance();
        //pInstance->fill();
        pInstance2->boil();
        pInstance2->drain();
    }
};


改进的单例模式,适用于多线程
class Singleton
{
public:
    static Singleton* getInstance()
    {
        if (m_pUniqueInstance == NULL)
        {
            //解决多线程问题
            //方法一
            //进入同步状态,采用双重检查,这是jave的做法
            static Singleton singleton = Singleton();
            m_pUniqueInstance = &singleton;

            //方法二
            //创建临界区
            //EnterCriticalSection(&g_cs);
            //if (m_pUniqueInstance == NULL) //双重检查
            //{
            //    m_pUniqueInstance = new Singleton();
            //}
            //LeaveCriticalSection(&g_cs);
        }

        return m_pUniqueInstance;
    }

private:
    Singleton(){}
    ~Singleton()
    {
        if (m_pUniqueInstance != NULL)
        {
            delete m_pUniqueInstance;
        }
    }

private:
    static Singleton* m_pUniqueInstance;
};

Singleton* Singleton::m_pUniqueInstance = 0;


http://www.jellythink.com/archives/82中有一个更好的示范,更简洁明了
#include <iostream>
using namespace std;

class Singleton
{
public:
	static Singleton *GetInstance()
	{
		static Singleton m_Instance;
		return &m_Instance;
	}

	int GetTest()
	{
		return m_Test++;
	}

private:
	Singleton(){ m_Test = 10; };
	int m_Test;
};

int main(int argc , char *argv [])
{
	Singleton *singletonObj = Singleton ::GetInstance();
	cout<<singletonObj->GetTest()<<endl;

	singletonObj = Singleton ::GetInstance();
	cout<<singletonObj->GetTest()<<endl;
}
分享到:
评论

相关推荐

    面向对象设计模式:Singleton 单件(创建型模式)

    李建忠面向对象设计模式视频精讲:Singleton 单件(创建型模式)

    Head First 设计模式 (五) 单件模式(Singleton pattern) C++实现

    单件模式(Singleton pattern)是设计模式中的一种结构型模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式常用于系统中需要频繁创建和销毁的对象,如日志服务、线程池或者数据库连接等...

    Head First设计模式和HeadFirst in java 源码以及23种设计模式关系图

    创建型模式关注对象的创建,如单例模式(Singleton)、工厂模式(Factory Method)、抽象工厂模式(Abstract Factory)和建造者模式(Builder)等,它们主要解决了对象实例化过程中的各种问题。结构型模式则涉及如何...

    head first 设计模式 高清完整版 pdf

    创建型模式关注对象的创建,如单例模式(Singleton)、工厂模式(Factory Method)和建造者模式(Builder)等,它们旨在控制实例化过程,降低类之间的耦合度。结构型模式关注如何组合现有的组件以形成更复杂的结构,...

    C#面向对象设计模式纵横谈-1.Singleton 单件(创建型模式)

    在提供的"1.Singleton 单件(创建型模式).wmv"视频文件中,可能详细讲解了Singleton模式的概念、实现方式、优缺点以及在C#中的具体应用实例,包括如何在实际项目中适当地使用和避免滥用Singleton模式。观看该视频可以...

    HeadFirst设计模式PPT

    创建型模式关注对象的创建,如单例模式(Singleton)、工厂方法模式(Factory Method)和建造者模式(Builder)。单例模式确保一个类只有一个实例,并提供全局访问点;工厂方法模式将对象的创建过程抽象化,允许子类...

    Head First Design Patterns 英文版 Head First设计模式

    其中,创建型模式如工厂方法(Factory Method)、抽象工厂(Abstract Factory)、单例(Singleton)和建造者(Builder)模式等,用于创建对象时提供更灵活和优雅的解决方案。结构型模式如适配器(Adapter)、外观...

    head first 设计模式 PDF电子书下载

    创建型模式关注于对象的创建,如单例模式(Singleton)、工厂模式(Factory Method)和抽象工厂模式(Abstract Factory)。结构型模式涉及如何组合类和对象以获得更大的结构,如适配器模式(Adapter)、装饰器模式...

    HeadFirst设计模式源代码

    创建型模式关注对象的创建,如单例模式(Singleton)、工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory)等,它们提供了一种在不指定具体对象的情况下创建对象的方法。结构型模式关注如何组合对象...

    HeadFirst设计模式JAVA版源码

    《HeadFirst设计模式JAVA版源码》是一份深入学习设计模式的重要资源,它基于流行的编程语言Java,旨在帮助开发者理解并应用设计模式于实际项目中。设计模式是软件工程中的重要概念,它代表了在特定场景下解决问题的...

    Head.First设计模式_PDF

    第1章到第11章陆续介绍的设计模式为Strategy、Observer、Decorator、Abstract Factory、Factory Method、Singleton、Command、Adapter、Facade、Template Method、iterator、Composite、State、proxy。最后三章比较...

    HeadFirst设计模式英文版

    整本书籍涵盖了23种设计模式,包括创建型模式、结构型模式和行为型模式,每种模式都通过实际的编程示例进行了详细的讲解。这些模式包括但不限于单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂...

    headfirst设计模式

    1. 创建型模式:如单例(Singleton)、工厂方法(Factory Method)、抽象工厂(Abstract Factory)、建造者(Builder)和原型(Prototype)。这些模式关注于对象的创建,帮助我们在不指定具体类的情况下,创建和管理...

    [中文]Head-First设计模式

    创建型模式关注对象的创建过程,如单例模式(Singleton)、工厂模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)和原型模式(Prototype)。这些模式帮助我们控制对象的实例化过程...

    Head First设计模式官方原码

    1. **创建型模式**:包括单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)和原型模式(Prototype)。这些模式主要关注对象的创建过程,使得对象的...

    Head First设计模式 源代码

    2. **创建型模式**:包括单例(Singleton)、工厂方法(Factory Method)、抽象工厂(Abstract Factory)、建造者(Builder)和原型(Prototype)模式。这些模式关注对象的创建过程,帮助我们隔离对象的创建细节,...

    Head First设计模式(含目录)

    创建型模式关注对象的创建,如单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)等,它们提供了创建对象的灵活方式,使得系统在运行时可以动态决定创建哪种类型的对象。...

    《Head.First设计模式》书中源代码(Java语言)

    《HeadFirst设计模式》是设计模式领域的一本经典著作,以其独特的教学方式和生动的插图深受初学者喜爱。这本书通过实例和互动式的学习方法,深入浅出地讲解了23种经典的设计模式。源代码作为理论知识的实践部分,...

    C#面向对象设计模式纵横谈(2):Singleton 单件(创建型模式)

    标题和描述均聚焦于"C#面向对象设计模式"之中的"Singleton单件(创建型模式)",这是一种在软件工程领域广泛运用的设计模式,其核心在于确保一个类只有一个实例,并提供一个全局访问点,以实现资源的有效管理和控制。...

Global site tag (gtag.js) - Google Analytics