首页 > 代码库 > 设计模式之单例模式

设计模式之单例模式

 意图

  保证一类仅有一个实例,并提供一个访问它的全局访问点。

适用性

  在下面的情况下可以使用Singleton模式:

  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
  • 当这个唯一的实例应该是通过子类可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时

UML图

技术分享

  • Instance

  ——定义一个Instance操作,允许客户访问它的唯一实例。

  ——可能负责创建它自己的唯一实例。

实现

保证一个唯一的实例

  为保证类示例的唯一性,需要提供一个统一的接口,一般是静态函数,来保证只有一个实例被创建。需要注意的是,客户只能通过Instance来访问这个单件。

//.h
class Singleton{
public:
	static Singleton * Instance();
protected:
	Singleton();
private:
	static Singleton * _isntance;
};
//.cpp
Singleton *Singleton::_isntance = 0;
Singleton *Singleton::Instance(){
	if(_isntance == 0){
		_isntance = new Singleton;
	}
	return _isntance;
}

  

创建Singleton类的子类

  为保证子类的唯一实例,GOF一书中提到了单件注册表(registry of singleton)。下面用一个map对象和虚函数GetName来模拟之。

//.h
class Singleton{
public:
	static void Register(const char* name, Singleton*);//注册子类单例
	static Singleton * Instance();
protected:
	Singleton();
	virtual const& string GetName();//子类继承该函数并定义实例名称
private:
	static Singleton * _instance;
	static std::map<string name, Singleton*> _registry;
	string _name;//单例类名称
};

//.cpp
Singleton *Singleton::_instance = 0;

Singleton::Singleton(){
	_name = "Singleton";
	Singleton::Register(_name, this);
}

const& string Singleton::GetName(){
	return _name;
}

Singleton *Singleton::Instance(){
	if(_instance == 0){
		_instance = _registry[GetName()];
	}
	return _instance;
}
//注册子类单例
void Singleton::Register(const char* name, Singleton* single){
	auto item = _registry.find(name);
	if(item != _registry.end()){
		return;
	}
	else{
		_registry.insert(std::make_pairs<name, single>);
	}
}

  子类MySingleton继承实现如下,只需要重新实现虚函数GetName,重新定义_name并调用子类的Register注册当前实例:

//.h
class MySingleton : public Singleton{
protected:
	MySingleton();
	virtual const& string GetName();
private:
	string _name;//单例类名称
};

//.cpp
MySingleton::MySingleton(){
	_name = "MySingleton";
	Singleton::Register(_name, this);
}
const& string  MySingleton::GetName(){
  return _name;
}

   子类必须要创建,否则不会被注册,可以在包含MySingleton的实现中创建:

static MySingleton theSingleton;

  

设计模式之单例模式