//---------------------------15/04/09----------------------------
//Singleton 单例模式-----对象创建型模式
/*
1:意图:
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2:动机
3:适用性:
1>当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
2>当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码
就能使用一个扩展的实例时。
4:结构:
Singleton:
static Instance()
{return uniqueInstance}
SingletonOperation()
GetSingletonData()
static uniqueInstance
singletonData
5:参与者:
Singleton:
1>定义一个Instance操作,允许客户访问它的唯一实例。Instance时一个类操作:
就是C++中的一个静态成员函数。
2>可能负责创建它自己的唯一实例。
6:协作:
客户只能通过Singleton的Instance操作访问一个Singleton实例。
7:效果:
1>对唯一实例的受控访问:
因为Singleton类封装它的唯一实例,所以它可以严格的控制客户怎样以及何时访问它。
2>缩小名空间:
Singleton模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染名空间。
3>允许对操作和表示的精华:
Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。
可以用需要的类的实例在运行时刻配置应用。<未知标记>
4>允许可变数目的实例:
通过改变允许访问Singleton实例的操作,来实现控制应用所使用的实例的数目。
5>比类操作更灵活:
另一种封装单件功能的方式是使用类操作:就是静态成员函数。
8:实现:
1>保证一个唯一的实例:
就是使用一个类操作来获得实例: */
//这样实现是有线程安全问题的
class Singleton
{
public:
static Singleton* Instance();
protected:
Singleton();
private:
static Singleton* _instance;
};
Singleton* Singleton::_instance =;
Singleton* Singleton::Instance()
{
if(_instance ==
)
_instance =new Singleton;
return _instance;
}
// 2>创建Singleton类的子类:
// 使用单件注册表:
class Singleton
{
public:
static
void Register(constchar* name, Singleton*);
static Singleton* Instance();
protected:
static Singleton* Lookup(constchar* name);
private:
static Singleton* _instance;
static map<char*,Singleton*> _registry;//感觉map更好用
};
Singleton* Singleton::Instance()
{
if(_instance ==
)
{
const
char* singletonName = getenv("SINGLETON");
_instance = Lookup(singletonName);
}
return _instance;
}
//子类注册:在构造函数中注册自己
MySingleton::MySingleton()
{
Singleton::Register("MySingleton",this);
}
//这个构造函数只有被调用了,注册表中才有MySingleton,所以要在实现文件中定义一个静态实例
static MySingleton theSingleton;
// 9:代码示例:
class MazeFactory
{
public:
static MazeFactory* Instance();
static
void Register(constchar* name, MazeFactory*);
protected:
MazeFactory();
static MazeFactory* Lookup(constchar* name);
private:
static MazeFactory* _instance;
static map<char*,MazeFactory*> _registry;
};
MazeFactory* MazeFactory::_instance =;
MazeFactory* MazeFactory::Instance()
{
if(_instance =
)
{
const
char* mazeName = getenv("MAZESTYLE");
_instance = Lookup(mazeName);
}
return _instance;
}
void MazeFactory::Register(constchar* name, MazeFactory* fac)
{
_registry.insert(std::make_pair(name,fac));
}
MazeFactory* MazeFactory::Lookup(constchar* name)
{
map<char*,MazeFactory*>::iterator it=_registry.find(name);
if(it != _registry.end())
return it->second;
return
;
}