设计模式单件(Singleton)---对象创建型模式
1.意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2.动机
对一些类来说,只有一个实例是很重要的。
方法:
1)一个全局变量使得一个对象可以被访问,但不能防止你实例化多个对象。
2)更好的方法是:让类自身负责保存它的唯一实例,这个类保证没有其他实例被创建,并可以提供一个访问该实例的方法 。
3.适用性
1)当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2)当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
4.结构
5.参与者
* Singleton
---定义一个Instance操作,允许客户访问他的唯一实例,Instance是一个类操作(C++中的一个静态成员函数)
---负责创建它自己的唯一实例 。
6.协作:
客户只能通过Singleton的Instance的操作访问一个Singleton的实例。
7.代码示例:
/*******************************************************
#ifdef Implementation1
class Singleton {
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
/*
*/
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance () {
if (_instance == 0) {
_instance = new Singleton;
}
return _instance;
}
/*
*/
#endif
/*
*/
#ifdef Implementation2
#include "List.H"
#include "stdlib.h"
class NameSingletonPair;
/*
*/
class Singleton {
public:
static void Register(char* name, Singleton*);
static Singleton* Instance();
protected:
static Singleton* Lookup(const char* name);
private:
static Singleton* _instance;
static List<NameSingletonPair>* _registry;
};
/*
*/
Singleton* Singleton::Instance () {
if (_instance == 0) {
const char* singletonName = getenv("SINGLETON");
// user or environment supplies this at startup
_instance = Lookup(singletonName);
// Lookup returns 0 if there's no such singleton
}
return _instance;
}
/*
*/
class MySingleton : public Singleton {
public:
MySingleton();
};
/*
*/
MySingleton::MySingleton() {
// ...
Singleton::Register("MySingleton", this);
}
/*
*/
static MySingleton theSingleton;
/*
*/
#endif
/*
*/
#ifdef Singleton
/*************************************************************************
*
*
*
* 以下是迷宫代码示例保证只有一个迷宫被创建
*
*
*
*************************************************************************/
class MazeFactory {
public:
static MazeFactory* Instance();
// existing interface goes here
protected:
MazeFactory();
private:
static MazeFactory* _instance;
};
/*
*/
MazeFactory* MazeFactory::_instance = 0;
MazeFactory* MazeFactory::Instance () {
if (_instance == 0) {
_instance = new MazeFactory;
}
return _instance;
}
/*
*/
#else
//MazeFactory* MazeFactory::_instance = 0;
#include "C++/MazeFactories.H"
#include "stdlib.h"
#include "strings.h"
/*
*/
MazeFactory* MazeFactory::Instance () {
if (_instance == 0) {
const char* mazeStyle = getenv("MAZESTYLE");
//?不懂这一句MAZESTYLE是哪冒出来的
/*
*/
if (strcmp(mazeStyle, "bombed") == 0) {
_instance = new BombedMazeFactory;
/*
*/
} else if (strcmp(mazeStyle, "enchanted") == 0) {
_instance = new EnchantedMazeFactory;
/*
*/
// ... other possible subclasses
/*
*/
} else { // default
_instance = new MazeFactory;
}
}
return _instance;
}
/*
*/
#endif
/*
*/
****************************************************************************//注:静态成员函数
//静态成员函数及一个简单的单件模式
1)像静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全体服务而不是为一个类的部分对象服务。这样就不需要定义一个全局函数,减少了全局或局部名字空间的占用,把这个函数移到了类的内部。当产生一个静态成员函数时,也就表达了与一个特定类的联系。静态成员函数不能访问一般的数据成员,它只能访问静态数据成员,也只能调用其他的静态成员函数。
2)静态成员函数没有this指针。
3)这是一个有趣的特点:因为静态成员对象的初始化方法,我们可以把上述类的一个静态数据成员放到那个类的内部。下面是一个例子,它把构造函数变成私有的,这样egg类只有一个唯一的对象存在,我们可以访问那个对象,但不能产生任何新的egg对象。
3)eg:
#include<iostream.h>
#include<stdio.h>
class egg
{
static egg* _instance; //必须为static数据成员
int i;
protected:
egg(int I){i=I;}
egg(){}
public:
static egg* Instance()
{
if(_instance==0)
_instance=new egg;
return _instance;
}
void Set(int I)
{i=I;}
int Get() const
{return i;}
};
egg* egg::_instance=0;
void main(void) //测试程序
{
// egg e(1); //wrong.如此构造要调用构造函数。
egg *pe1=egg::Instance();
pe1->Set(50);
egg *pe2=egg::Instance();
cout<<"第一个egg,i="<<pe1->Get()<<endl;
cout<<"第二个egg,i="<<pe2->Get()<<endl;
getchar();
}