设计模式之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();






posted on 2012-03-14 16:47  菜丝inside  阅读(277)  评论(0编辑  收藏  举报