[创建型模式] head first 设计模式之单件模式(Singleton)

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

2 适用性
在下面的情况下可以使用Singleton模式
[color=red]a)当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时;
b)当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需要更改代码就能适用一个扩展的实例时;[/color]

3 优点
[color=red] a)对唯一实例的受控访问;
因为Singleton类封装它的唯一实例,所以它可以严格的控制客户怎样以及何时访问它;

b)缩小名空间
Singleton模式是对全局变量的一种改进,它避免了那些存储唯一实例的全局变量名空间

c)允许对操作和表示的精化;
Singleton类可以有子类,而且这个扩展类的实例来配置一个应用时很容易的。你可以用你所需要的类的实例在运行时刻配置应用。

d)允许可变数目的实例;

e)比类操作更灵活;[/color]

[img]http://t25-3.yunpan.360.cn/p/800-600.bcf593b6c742a90de0a298edc3894d661cdc74a3.f305c7.jpg?t=a344bfb34b846467f2df389c48ad5ce8&d=20130821[/img]

标准的单例模式,仅适用于单线程

//
class ChocolateBoiler
{
private:
ChocolateBoiler()
{
m_bEmpty = true;
m_bBoiled = false;
}

public:
static ChocolateBoiler* getInstance()
{
if (m_pUniqueInstance == NULL)
{
//标准的单例模式,多线程下面有可能创建多个实例
m_pUniqueInstance = new ChocolateBoiler();
}

return m_pUniqueInstance;
}

~ChocolateBoiler()
{
if (m_pUniqueInstance != NULL)
{
delete m_pUniqueInstance;
}
}

void fill()
{
if (isEmpty())
{
m_bEmpty = false;
m_bBoiled = false;
//在锅炉内填满巧克力和牛奶的混合物
}

if (m_bEmpty)
{
cout << "[ChocolateBoiler::fill] Empty\n";
}
else
{
cout << "[ChocolateBoiler::fill] Full\n";
}

if (m_bBoiled)
{
cout << "[ChocolateBoiler::fill] Boiled\n";
}
else
{
cout << "[ChocolateBoiler::fill] Not Boil\n";
}
}

void drain()
{
if (!isEmpty() && isBoiled())
{
//排出煮沸的巧克力和牛奶
m_bEmpty = true;
}

if (m_bEmpty)
{
cout << "[ChocolateBoiler::drain] Empty\n";
}
else
{
cout << "[ChocolateBoiler::drain] Full\n";
}
}

void boil()
{
if (!isEmpty() && !isBoiled())
{
//将炉内物煮沸
m_bBoiled = true;
}

if (m_bBoiled)
{
cout << "[ChocolateBoiler::boil] Boiled\n";
}
else
{
cout << "[ChocolateBoiler::boil] Not Boil\n";
}
}

bool isEmpty()
{
return m_bEmpty;
}

bool isBoiled()
{
return m_bBoiled;
}

private:
bool m_bEmpty;
bool m_bBoiled;
static ChocolateBoiler* m_pUniqueInstance;
};

ChocolateBoiler* ChocolateBoiler::m_pUniqueInstance = 0;

class ChocolateBoilerTestDrive
{
public:
void run()
{
ChocolateBoiler* pInstance = ChocolateBoiler::getInstance();
pInstance->fill();
pInstance->boil();
pInstance->drain();

ChocolateBoiler* pInstance2 = ChocolateBoiler::getInstance();
//pInstance->fill();
pInstance2->boil();
pInstance2->drain();
}
};


改进的单例模式,适用于多线程

class Singleton
{
public:
static Singleton* getInstance()
{
if (m_pUniqueInstance == NULL)
{
//解决多线程问题
//方法一
//进入同步状态,采用双重检查,这是jave的做法
static Singleton singleton = Singleton();
m_pUniqueInstance = &singleton;

//方法二
//创建临界区
//EnterCriticalSection(&g_cs);
//if (m_pUniqueInstance == NULL) //双重检查
//{
// m_pUniqueInstance = new Singleton();
//}
//LeaveCriticalSection(&g_cs);
}

return m_pUniqueInstance;
}

private:
Singleton(){}
~Singleton()
{
if (m_pUniqueInstance != NULL)
{
delete m_pUniqueInstance;
}
}

private:
static Singleton* m_pUniqueInstance;
};

Singleton* Singleton::m_pUniqueInstance = 0;


[url]http://www.jellythink.com/archives/82[/url]中有一个更好的示范,更简洁明了

#include <iostream>
using namespace std;

class Singleton
{
public:
static Singleton *GetInstance()
{
static Singleton m_Instance;
return &m_Instance;
}

int GetTest()
{
return m_Test++;
}

private:
Singleton(){ m_Test = 10; };
int m_Test;
};

int main(int argc , char *argv [])
{
Singleton *singletonObj = Singleton ::GetInstance();
cout<<singletonObj->GetTest()<<endl;

singletonObj = Singleton ::GetInstance();
cout<<singletonObj->GetTest()<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值