但凡成为大家公认的模式,都是有一些不可小觑的威力,今天分享一个简单的设计模式:单例模式。
单例模式用于一些只希望有一个实例的类或者只希望执行一次的操作:校长只能有一个、老板只能有一个、用户点击弹窗只希望弹出一次。用全局变量等方式也可以实现,但是多了很多判断和处理代码,并且职责模糊,类的唯一实例化是交给调用者进行判断处理的,每调用一次就要做一次判断,重复了很多工作量,如果是多线程编程,不好的同步设计更是会导致程序卡顿。
如果还在为这些重复工作苦恼,是时候着手单例模式了:设计简单、调用方便、一劳永逸。
用一句话来描述单例模式:私有化的构造函数和公有化的静态获取实例方法。
单例模式设计的示例比较简单,不做赘述:
//饿汉式单例
class singletonhungry
{
public:
static singletonhungry* GetInstance();
private:
static singletonhungry* m_Ins;
singletonhungry(){}
singletonhungry(const singletonhungry&) {}
};
//static成员的初始化在进入main函数之前完成,随程序退出而终结生命,对象在程序生命周期内一直存在且单例
singletonhungry* singletonhungry::m_Ins = new singletonhungry;
singletonhungry* singletonhungry::GetInstance()
{
return m_Ins;
};
//懒汉式单例
class singletonlazy
{
public:
static singletonlazy* GetInstance();
private:
static singletonlazy* m_Ins;
singletonlazy() {}
singletonlazy(const singletonlazy&) {}
};
singletonlazy* singletonlazy::m_Ins = NULL;
singletonlazy* singletonlazy::GetInstance()
{
if(m_Ins == NULL)
{
//仅在程序需要对象时才被加载
m_Ins = new singletonlazy;
}
return m_Ins;
};
//多线程模式的懒汉单例
class multithreadsingletonlazy
{
public:
static multithreadsingletonlazy* GetInstance();
private:
static multithreadsingletonlazy* m_Ins;
static HANDLE hMutex;
multithreadsingletonlazy() {}
multithreadsingletonlazy(const multithreadsingletonlazy& ) {}
};
multithreadsingletonlazy* multithreadsingletonlazy::m_Ins = NULL;
HANDLE multithreadsingletonlazy::hMutex = CreateMutex(NULL, FALSE, TEXT("singleton"));
multithreadsingletonlazy* multithreadsingletonlazy::GetInstance()
{
if(m_Ins == NULL)
{
WaitForSingleObject(hMutex, INFINITE);
if(m_Ins == NULL)
{
m_Ins = new multithreadsingletonlazy;
}
ReleaseMutex(hMutex);
}
return m_Ins;
}
//验证一下是否同一个实例
void foo45()
{
singletonlazy* lazy1 = singletonlazy::GetInstance();
singletonlazy* lazy2 = singletonlazy::GetInstance();
singletonhungry* hungry1 = singletonhungry::GetInstance();
singletonhungry* hungry2 = singletonhungry::GetInstance();
multithreadsingletonlazy* msl1 = multithreadsingletonlazy::GetInstance();
multithreadsingletonlazy* msl2 = multithreadsingletonlazy::GetInstance();
if(lazy1 == lazy2)
{
cout << "lazy1 equal to lazy2" << endl;
}
if(hungry1 == hungry2)
{
cout << "hungry1 equal to hungry2" << endl;
}
if(msl1 == msl2)
{
cout << "msl1 equal to msl2" << endl;
}
}
仅用了13行就完成了非常实用的单例模式,仔细想一想,还真是有点小激动呢!
小结:单例模式和简单工厂模式有一些内在的共通特性,职责内敛,由类本身负责实例,所有的外界调用者只需要打声招呼“嗨,给我一个实例”,大大减少了重复代码和错误概率,本身的实现也很简单,时时记得这个好帮手哟。