设计模式之Singleton
Singleton是我项目中运用最多的设计模式了,虽然简单,却能大大降低模块耦合性。通过该模式,最多只能创建该类的一个实例。个人理解,Singleton就不再需要别的模块来聚合本模块,其表现形式最大特点就是构造函数的访问权限是private的,由第一个依赖本模块的其它模块进行实例化。笔者一直从事安全软件的研发,会在软件运行初期通过调用各个模块的Init()来实现单例的实现,而这个过程由于在初始化线程中串行执行,也有效避免了多线程下单例的互斥问题。不过下述文章仍会介绍下多线程开发单线程互斥问题。
类的声明:
View Code
//Singleton.h
namespace DP{
#ifndef _SINGLETON__H_
#define _SINGLETON__H_
class CSingleton{
private:
CSingleton(){
};
~CSingleton(){
};
static CSingleton* instance;
public:
static CSingleton* Singleton();/*Singleton()函数必须设置成公有属性*/
void Print();/*本模块对外提供的操作方法实例*/
};
}
#endif/*_SINGLETON__H_*/
类的成员变量的实现:
View Code
//Singleton.cpp
#include "Singleton.h"
#include <stdio.h>
using DP::CSingleton;
CSingleton* CSingleton::instance = NULL;
CSingleton* CSingleton::Singleton()
{
if (NULL ==instance)
{
instance = new CSingleton();
}
return instance;
}
void CSingleton::Print()
{
printf("this instance is call\n");
}
单例模式主要具备如下特征:
1. 将构造函数声明为私有的,防止在类外生成对象;
2. 提供静态方法Singleton()来返回自己的实例,别的模块在依赖该模块时,比如需要该模块提供的操作Print()时,只需要CSingleton::Singleton()->Print();
3. CSingleton类中有一个静态变量instance,用于指向唯一自己模块实例的指针,在初始化的时候为NULL;
4. 在Singleton()是单例模式的核心体现,会在第一次被调用时进行自我实例化。
然而,Singleton()中的if(NULL==instance)判断,在多线程程序中会出现竞争冒险,这时候我们就采取多线程互斥的方法。
采用DCLP(Double Check Locking Pattern)实现互斥。
互斥锁的声明和实现(使用Windows平台API,以后可以考虑posix接口实现,可以针对跨平台操作):
//Mutex.h
#ifndef _MUTEX__H_
#define _MUTEX__H_
#include "Windows.h"
class CMutex{
public:
CMutex();
~CMutex();
void Lock();
void UnLock();
private:
HANDLE m_mutex;
};
#endif/*_MUTEX__H_*/
View Code
//Mutex.cpp
#include "Mutex.h"
CMutex::CMutex()
{
m_mutex = CreateMutex(NULL, false, NULL);
}
CMutex::~CMutex()
{
CloseHandle(m_mutex);
}
void CMutex::Lock()
{
WaitForSingleObject(m_mutex, INFINITE);
}
void CMutex::UnLock()
{
ReleaseMutex(m_mutex);
}
Sinleton()模式声明和实现:
//Singleton.h
#ifndef _SINGLETON__H_
#define _SINGLETON__H_
#include "../Mutex/Mutex.h"
namespace DP{
class CSingleton{
private:
CSingleton(){
};
~CSingleton(){
};
static CMutex mutex_visit;
static CSingleton* instance;
public:
static CSingleton* Singleton();/*Singleton()函数必须设置成公有属性*/
void Print();/*本模块对外提供的操作方法实例*/
};
}
#endif/*_SINGLETON__H_*/
View Code
//Singleton.cpp
#include "Singleton.h"
#include <stdio.h>
using DP::CSingleton;
CMutex CSingleton::mutex_visit;
CSingleton* CSingleton::instance = NULL;
CSingleton* CSingleton::Singleton()
{
if (NULL ==instance)//第一层判断, 避免下面line12~line16频繁执行
{
mutex_visit.Lock();
if(NULL==instance){//因为第一层判断没有加锁,因此只靠第一层判断无法做到避免竞争冒险
instance = new CSingleton();
}
mutex_visit.UnLock();
}
return instance;
}
void CSingleton::Print()
{
printf("this instance is call\n");
}
示例代码:
CSingleton::Singleton()->Print();