设计模式随笔(一):单件模式(Singleton Pattern)

来源:互联网 发布:淘宝商品表设计 编辑:程序博客网 时间:2024/06/16 22:42

单件模式(Singleton Pattern

 

作者:Will LeeQQ31940767EMailw.lee@live.cn

声明:本文可用于个人学习、参考、私下传阅,未经本人授权严禁用于商业用途。有朋友转载或引用本文请注明文章作者和出处,感谢!!

 

1          模式简介

singleton是设计模式家族中的小弟弟,重量轻,没有复杂的经历,很单纯,所以叫单件(just a joke)。因为简单,容易被人洞悉,所以经常被人唤来唤去,singleton是软件设计者们最常使用的模式之一。

简单,却不乏内涵。singleton可以让一个类在全局或局部范围(如一个线程)内仅被创建一次,并始终维持一个(注意不是多个)对象,面向公众服务,帮助客户节省存储资源。所以说,singleton不仅有用,而且环保,^^

 

2          模式结构

singleton结构如1所示。

 

图1 singleton模式结构

模式涉及两个角色:

1. Singleton:单件对象,本文主角,接下来重点围绕它来转。

2. ClientSingleton的客户程序。客户就是上帝(really?)的年代,Singleton也得与时俱进,所以Singleton的工作就是:如何博得Client的满意。

Client希望Singleton吃的少,干的多(多么“厚道”而普遍的要求)。

具体一点,就是:

Client使用的范围内,Singleton只能实例化一个对象,并提供一个接口,不管Client在何时何地想起Singleton都能够通过该接口找到它,并给它分派任务,也就是随叫随到吧(can you? )。Singleton则须保持友好的界面,甭管有事没事,见到Client就问:may I help you, sir?地道的......

3          核心思想

一个字:满足Client要求。

全局或局部范围内,保持唯一的实例,并提供一个public接口,供Client访问该实例,当然,对该接口的引用不需要Client另外再创建对象。

 

4          实现关键点

说起来容易,做起来就

从以下几个方面,说明Singleton模式在实现(采用C++)过程中的一些关键点。

1. 保存唯一的实例

Singleton类中定义一个指向自身类型的静态的指针变量,也就是一个静态Singleton类型指针(后面称呼该指针为:Singleton指针),用于保存Singleton实例对象。

 

2. 创建唯一的实例

何时何地创建这唯一的实例?选择不止一种:

a. 在程序一开始的地方创建。此时Singleton需要提供一个接口,供Client将创建好的实例对象传递给Singleton指针。一般设计一个带参数的Instance(Singleton *)方法来完成该职责,代码示例如下:

void Singleton::Instance(Singleton *pInstance)
{
    m_instance = pInstance;

b. 什么时候使用,什么时候创建。也就是在Instance方法中创建,代码示例如下: 

Singleton * Singleton::Instance()
{
    if (NULL == m_instance)
    {
        m_instance = new Singleton;
    }

    return m_instance;
}

显然,在第一次引用Instance方法时,Singleton对象即被创建。

就我个人而言,更喜欢第二种,:)

 

3. 访问唯一的实例

设计一个静态Instance方法,该方法返回唯一实例的指针,供Client使用。如同第2条中的描述,Instance方法可能还承担创建Singleton对象的责任。

 

4. 如何保证实例的唯一性

怎样才能保证Singleton类只被创建一次呢?好吧,也有不同的选择:

a. 人为的遵守,也就是说靠Client的自觉性,这,要求Client仅在程序一开始创建一次,或者干脆不创建(在Instance()中创建的手法),只通过Singleton::Instance()引用Singleton对象。核心就是靠自觉,靠人性,而众所周知,最靠不住的就是人假如Client不守规矩,在程序某个地方来一句:new Singleton怎么办呢?别急,还有第二种方法。

b. 代码级强制遵守,强制客户遵守该规则,想创建也创建不了。听起来好牛啊,做法却浅显易懂,让人大跌眼镜:将Singleton构造函数声明为protectedprivate…

 

根据上面几条的描述,一个简单的Singleton类声明大概就像下面的:

class Singleton
{
public:
    static Singleton * Instance();
protected:
    Singleton()
    {
    }
private:
    static Singleton *m_instance;
};

 

5.         扩展

一般简单的Singleton设计,Singleton包裹的就是一个应用对象。

想复杂一些,或者显得更有技术含量,Singleton类可容纳多个对象,相当于一个单件对象管理器角色。此时一个简单的静态Singleton指针已经不能满足要求,可能需要一个复合数据结构的容器变量来存储单件对象。比如一个HASH表,存放索引和具体单件对象的映射关系。

相应的,Instance()方法也需要扩展,增加一个参数(index),用于指定访问哪一个单件实例,Instance(index)方法在HASH表中去查找,查找不到就创建

既然大家都共用Instance(index)方法,那么所有单件对象需要有一个公共的superclass,用于指明Instance(index)方法的返回值,也方便Client引用Singleton对象,这也牵涉到面向对象设计的另一特性:抽象。

 

更多有趣的,等待你的摸索。

 

5          设计样例

懒得举例了,现在你还不会吗?

原创粉丝点击