模式分类:
1. 目的分类
创建型(creatinal)
机构型(structural):类与对象间的组合,避免继承的耦合
行为型(behavioral):类与对象交互中的职责分配,组件间的交互,隔离变化
2. 范围分类
类模式处理类与子类的静态关系
对象模式处理对象间的动态关系
单件模式:
1.动机(tivation)
在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。
如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?
这应该是类设计者的责任,而不是使用者的责任
2.意图(Intent)保证一个类仅有一个实例,并提供一个该实例的全局访问点。
——《设计模式》GOF
3. 结构
4. 单线程Singleton模式的几个要点
Singleton模式中的实例构造器可以设置为protected以允许子类派生。
Singleton模式一般不要支持ICloneable接口,因为这可能会导致多个对象实例,与Singleton模式的初衷违背。
Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式的初衷违背。
Singletom模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没有必要对其销毁进行特殊的管理。
不能应对多线程环境:在多线程环境下,如直接使用传统Singleton模式仍然有可能得到Singleton类的多个实例对象
单线程Code:
class ServeChannel
{
private static ServeChannel FInstance;
private ServeChannel() { }
public static ServeChannel Instance//如果有参数时,则不能用属性而应改为函数
{
get {
if (FInstance == null) {//此实现导致无法多线程
FInstance = new ServeChannel();
}
return FInstance;
}
}
}
test{
ServeChannel t = ServeChannel.Instance;
}
多线程Code:1。传统实现,C#下实现
class ServeChannel
{
private static volatile ServeChannel FInstance; //不允许编译器对实现代码顺序微调
private static object FLocker = new object();
private ServeChannel() { }
public static ServeChannel Instance
{
get {
if (FInstance == null) {
lock (FLocker)
{
if (FInstance == null)
FInstance = new ServeChannel();
}
}
return FInstance;
}
}
}
test{
ServeChannel t = ServeChannel.Instance;
}
这是比较传统的方案而下面的是C#中很经典的的实现,它利用静态构成函数的特点将代码简化,缺点是不支持构造时传参数,但一般的应用中是可以满足的,有人建议在构造后加一个初始化的函数,我认为不会,这方式不是通用的习惯,新手加入是很容易漏掉。
class ServeChannel
{
public static readonly ServeChannel Instance = new ServeChannel();
private ServeChannel() { }
}
此实现相当于:
class ServeChannel
{
public static readonly ServeChannel Instance;
static ServeChannel()//保证了多线程安全
{
Instance = new ServeChannel();
}
private ServeChannel() { }
}