设计模式之四:单例模式
来源:互联网 发布:淘宝客服哪里培训课程 编辑:程序博客网 时间:2024/05/16 04:33
好看的排版,尽在博客园 设计模式之四:单例模式
2014-01-18 星期六 11:12:42
Singleton,继续GOF。
1、Intent
Ensure a class only has one instance, and provide a global point of access to it.
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2、Also Known As
3、Motivation
It's important for some classes to have exactly one instance. Although there can be many printers in a system, there should be only one printer spooler. There should be only one file system and one window manager. A digital filter will have one A/D converter. An accounting system will be dedicated to serving one company.
对一些类来说,只有一个实例是很重要的。虽然系统中可以有许多打印机,但却只应该有一个打印假脱机( printer spooler) ,只应该有一个文件系统和一个窗口管理器。一个数字滤波器只能有一个A / D转换器。一个会计系统只能专用于一个公司。
How do we ensure that a class has only one instance and that the instance is easily accessible? A global variable makes an object accessible, but it doesn't keep you from instantiating multiple objects.
我们怎么样才能保证一个类只有一个实例并且这个实例易于被访问呢?一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象。
A better solution is to make the class itself responsible for keeping track of its sole instance. The class can ensure that no other instance can be created (by intercepting requests to create new objects), and it can provide a way to access the instance. This is the Singleton pattern.
一个更好的办法是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求) ,并且它可以提供一个访问该实例的方法。
这就是Singleton模式。
4、Applicability
Use the Singleton pattern when
● there must be exactly one instance of a class, and it must be accessible to clients from a wellknown access point.
● when the sole instance should be extensible by subclassing, and clients should be able to use an extended instance without modifying their code.
在下面的情况下可以使用Singleton模式
● 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
● 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
5、Structure
6、代码
#include <iostream>
#include <memory>
#include <cstring>
#include <unistd.h>
#define STATIC_IN_CLASS
//实际应用中可以宏定义
///////////////// 单件模式
#define PATTERN_SINGLETON_DECLARE(classname) \
static
classname * instance();
#define PATTERN_SINGLETON_IMPLEMENT(classname) \
classname * classname::instance() \
{ \
static
classname * _instance = NULL; \
if
( NULL == _instance) \
{ \
_instance =
new
classname; \
} \
return
_instance; \
}
class
CSingleton
{
public
:
PATTERN_SINGLETON_DECLARE(CSingleton);
protected
:
CSingleton()
//not public
{
std::cout<<
"CSingleton::CSingleton()"
<<std::endl;
}
public
:
~CSingleton(){};
public
:
void
is_singel()
{
std::cout<<
"is_singel(),m_test = "
<<m_test<<std::endl;
}
#if 0
CSingleton& operator=(
const
CSingleton& rhs)
{
if
(
this
!= &rhs)
{
m_test = rhs.m_test;
}
std::cout<<
"operator="
<<std::endl;
return
*
this
;
}
const
CSingleton& rhs
);CSingleton& operator=(
const
CSingleton& rhs);
private
:
int
m_test;
static
CSingleton* _instance;
//按gof类图放在里面
static
const
int
t = 0;
/*静态数据在c++中只有 static const int t = 0;
可以初始化。
其他都要在类的外面。
*/
};
//PATTERN_SINGLETON_IMPLEMENT(CSingleton); //ok
CSingleton* CSingleton::_instance = NULL;
CSingleton * CSingleton::instance()
{
//lock
if
( NULL == _instance)
{
_instance =
new
CSingleton;
}
else
{
//exception
}
return
_instance;
}
#define g_CSingleton (*CSingleton::instance())
#define g_pCSingleton (CSingleton::instance())
int
main(
int
argc,
char
*argv[])
{
//只有一次输出"CSingleton::CSingleton()"
CSingleton *ps1 = CSingleton::instance();
ps1->is_singel();
CSingleton *ps2 = g_pCSingleton;
ps2->is_singel();
CSingleton s2 = *CSingleton::instance();
s2.is_singel();
CSingleton s21 = g_CSingleton;
s21.is_singel();
sleep(1);
(*CSingleton::instance()).is_singel();
std::cout << std::endl <<
"This is a Singelton Antother"
<<std::endl;
std::cout <<
"Not Get By instance()"
<<std::endl;
#
if
0
//如果是public的话,可以编译通过。即违背了singleton
CSingleton s3;
s3.m_test = 3;
CSingleton s4=s3;
s4.is_singel();
s4 = *CSingleton::instance();
s4.is_singel();
#endif
return
0;
}
7、扩展--单件注册表
A more flexible approach uses a registry of singletons. Instead of having Instancedefine the set of possible Singleton classes, the Singleton classes can register their singleton instance by name in a well-known registry.
一个更灵活的方法是使用一个单件注册表(registry of singleton ) 。可能的Singleton类的集合不是由Instance定义的, Singleton类可以根据名字在一个众所周知的注册表中注册它们的单件实例。
The registry maps between string names and singletons. When Instanceneeds a singleton, it consults the registry, asking for the singleton by name. The registry looks up the corresponding singleton (if it exists) and returns it. This approach frees Instancefrom knowing all possible Singleton classes or instances. All it requires is a common interface for all Singleton classes that includes operations for the registry:
这个注册表在字符串名字和单件之间建立映射。当 Intance需要一个单件时,它参考注册表,根据名字请求单件。注册表查询相应的单件(如果存在的话)并返回它。这个方法使得 Intance不再需要知道所有可能的 singleton类或实例。它所需要的只是所有 Singleton类的一个公共的接口,该接口包括了对注册表的操作:
#if 1
class
Singleton
{
public
:
static
void
Register(
const
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;
}
#endif
Singleton类在何处注册它们自己?一种可能是在它们的构造器中。例如, MySingleton子类可以像下面这样做:
MySingleton::MySingleton()
{
// ...
Singleton::Register(
"MySingleton"
,
this
);
}
- 设计模式之四:单例模式
- 设计模式(四)之单例模式
- Java模式设计之单例模式(四)
- (四)单例设计模式
- 设计模式(四)--单例模式(1)
- 设计模式(四)--单例模式(2)
- 设计模式四:单例模式
- 设计模式(四)---单例模式
- 设计模式(四)单例模式
- iOS设计模式(四) 单例模式
- 设计模式(四) 单例模式
- 大话设计模式(四)单例模式
- 设计模式(四)单例模式
- 设计模式之(四)单态Singleton
- 设计模式之 单例设计模式
- 设计模式之 单例设计模式
- 设计模式之单例设计模式
- 设计模式之-----------单例设计模式
- hdu 1176 免费馅饼
- INT_MIN
- Lesson 3 Part 1 Locally weighted regression
- create_workqueue 和create_singlethread_workqueue的区别
- Trapping Rain Water
- 设计模式之四:单例模式
- 使用SwingWorker之二
- The content of element type "sqlMapConfig" is incomplete, it must match "(properties?,settings?,resu
- 详解ORACLE中游标的生命周期
- 【XCode】Managing Images with Xcode 5 Asset Catalogs
- HashMap的工作原理
- 使用SwingWorker之三
- Erlang基础 - 函数、子句、子句保护式
- cocos2d-x游戏开发系列教程-超级玛丽03-main函数