设计模式之单件模式
2013-05-28 12:39
453 查看
单件模式 别名:Singleton
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点;
适用性:
1.当类只能有一个实例,而客户可以从一个众所周知的访问点访问它时。
2.当这个唯一实例应该是通过子类化可扩展的,并且客户端应该无需更改代码就能使用一个扩展实例时。
优点:
1.对唯一实例的受访控制;
2.缩小名空间,避免全局变量污染;
3.允许通过子类对操作和表示进行精化;
4.可以扩充为可变数目的实例(这样就形成对象池模式);
5.比类操作更灵活(C++、C#中类操作不能设计为可变数目实例,且类操作亦无法实现为虚函数)
缺点:
无法在语法层面做到既保证仅有一实例,又能被其client扩展。
参与者:Singleton
实现:
1.封闭构造函数,提供静态函数作为访问实例的接口;
2.采用protected构造函数,允许子类进行扩展与动态配置;
3.利用注册方式为某些类提供一个全局访问点
相关:AbstractFactory、Builder、Prototype这些类通常采用单件模式
延伸:
Microsoft:在.net中,微软从语法层面利用静态类提供了单件模式的实现,但如果该单件类的实例化依赖于某运行时变量,则需要自己编写相关单件类,否则,我没发现任何一种设计比微软语法层面机制更好。
示例:
C#:此类为一个支持继承体系的singleton工具类,此类只能提供全局访问点,不能提供语法层面的单件约束。
客户端使用:
代码参见:SyntCore,EnvirLib工程。
C++:下面是一个利用模板机制实现的支持继承(含多重继承)的C++单件类,其实现思路与上述C#类似:
下面的CProgram类实现了单件模式,其作用是为应用程序提供一种全局设置:
上述两个单件类均由于支持继承,其基类的构造函数不能为private,因此无法在语法层面保证其不被二次实例化,只能借助运行时检查防止其创建多个实例。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点;
适用性:
1.当类只能有一个实例,而客户可以从一个众所周知的访问点访问它时。
2.当这个唯一实例应该是通过子类化可扩展的,并且客户端应该无需更改代码就能使用一个扩展实例时。
优点:
1.对唯一实例的受访控制;
2.缩小名空间,避免全局变量污染;
3.允许通过子类对操作和表示进行精化;
4.可以扩充为可变数目的实例(这样就形成对象池模式);
5.比类操作更灵活(C++、C#中类操作不能设计为可变数目实例,且类操作亦无法实现为虚函数)
缺点:
无法在语法层面做到既保证仅有一实例,又能被其client扩展。
参与者:Singleton
实现:
1.封闭构造函数,提供静态函数作为访问实例的接口;
2.采用protected构造函数,允许子类进行扩展与动态配置;
3.利用注册方式为某些类提供一个全局访问点
相关:AbstractFactory、Builder、Prototype这些类通常采用单件模式
延伸:
Microsoft:在.net中,微软从语法层面利用静态类提供了单件模式的实现,但如果该单件类的实例化依赖于某运行时变量,则需要自己编写相关单件类,否则,我没发现任何一种设计比微软语法层面机制更好。
示例:
C#:此类为一个支持继承体系的singleton工具类,此类只能提供全局访问点,不能提供语法层面的单件约束。
public abstract class Singleton<T> where T : Singleton<T>, new() { private static T _singleton = default(T); protected Singleton() { System.Diagnostics.Trace.Assert(_singleton == null); } public static T Instance<U>() where U:T,new() { lock (typeof(T)) { return _singleton = (_singleton ?? new U()); } } }
客户端使用:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sysnet.DesignPatterns; using Sysnet.Security.Rights; using Sysnet.Security; namespace Sysnet.Environments.Rights { public class RightManager : Singleton<RightManager>,IRightManager //RightManager单件类为最终的客户端调用的单件类,然而从设计上来说,其可能继承于一个具备一定通用功能的非单件权限管理类。这样就涉及到一个多重继承的例子,其一个父类保证该实例的单件化,另一个父类提供基本的权限管理功能。C#语法层面不支持多重继承,关于在C#中的多重继承的设计,在适配器模式中进行描述。 { public bool Verify(ISession session,IRequest requst) { return true; } } }
代码参见:SyntCore,EnvirLib工程。
C++:下面是一个利用模板机制实现的支持继承(含多重继承)的C++单件类,其实现思路与上述C#类似:
template<typename T> class SingleTon { public: static T* ms_SingleTon; SingleTon() { assert(!ms_SingleTon); int offset = (int)(T*)1 - (int)(SingleTon<T>*)(T*)1; ms_SingleTon = (T*)((int)this + offset); } ~SingleTon() { assert(ms_SingleTon); ms_SingleTon = 0; } static T& GetSingleTon() { assert(ms_SingleTon); return *ms_SingleTon; } static T* GetSingleTonPtr() { return ms_SingleTon; } }; // 初始化 template<typename T> T* SingleTon<T>::ms_SingleTon = 0;
下面的CProgram类实现了单件模式,其作用是为应用程序提供一种全局设置:
#pragma once #include "../Include/Singleton.h" #include "WindExt.h" class WINDEXT_API CProgram : public SingleTon<CProgram> { public: typedef void (* RepeatRunCallBack)(); private: GUID m_guidApplication; HANDLE m_hMutex; DECLARE_PROPERTY(RepeatRunCallBack,RepeatRunCallBack); public: CProgram(); void SetApplicationId(GUID &guid); void SetApplicationIdByResource(UINT resourceid); void SetErrorMode(); void SetRunOnce(); virtual ~CProgram(void); };
上述两个单件类均由于支持继承,其基类的构造函数不能为private,因此无法在语法层面保证其不被二次实例化,只能借助运行时检查防止其创建多个实例。
相关文章推荐
- C++编程思想(卷二):设计模式:单件
- 设计模式(五)[单件(Singleton)模式]
- 设计模式 6 —— 单件模式
- 面向对象设计模式纵横谈:Singelton单件模式(笔记记录)
- 1.设计模式 - Singleton模式(单件模式)
- C语言和设计模式(单件模式)
- 设计模式复习笔记(单件)
- C++设计模式:单件模式
- 设计模式学习之单件模式(Singleton)
- C#设计模式——单件模式
- 设计模式--单件实现C++
- 设计模式学习——单件模式
- 设计模式--创建型-Singleton(单例单件)
- 设计模式之单件模式
- VB.net设计模式之单件模式(singleton)
- 脚跟脚设计单件模式—第一脚
- 设计模式---单件
- 系统架构技能之设计模式-单件模式 推荐
- [设计模式] 设计模式面面观(3):单件模式(Singletion)-创建型模式
- PHP设计模式4-单件和单态模式