1、模式分类
1)从目的来看:
A:创建型(Creational)模式:负责对象创建。
B:结构型(Structural)模式:处理类与对象间的组合。
C:行为型(Behavioral)模式:类与对象交互中的职责分配。
2)从范围来看:
A:类模式处理类与子类的静态关系。
B:对象模式处理对象间的动态关系。
2、动机(Motivation)
1)在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。
2)如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?
3)这应该是类设计者的责任,而不是使用者的责任。
3、意图(Intent)
保证一个类仅有一个实例,并提供一个该实例的全局访问点。
——《设计模式》GoF
4、单线程Singleton模式实现
public class Singleton
{
private static Singleton _instance;
//重点在这,私有构造,不让外部new
private Singleton()
{
}
public static Singletoon Instance
{
get
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
}
class Test
{
public static void Main()
{
Singleton t1 = Singleton.Instance;
Singleton t2 = Singleton.Instance;
//查看t1, t2的引用是否相等
Console.WriteLine(Object.ReferenceEquals(t1, t2) == true);
}
}
5、单线程Singleton模式的几个要点
1)Singleton模式中的实例构造器可以设置为protected以允许子类派生。
2)Singleton模式一般不要支持ICloneable接口,因为这可以会导致多个对象实例,与Singleton模式的初衷违背。因为IClonealbe是克隆浅拷钡。
3)Singleton模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与Singleton模式初衷违背。序列化能实现克隆的深拷钡。
4)Singleton模式只考虑到了对象创建的管理,没有考虑对象销毁的管理。就支持垃圾回收的平台和对象的开销来讲,我们一般没有必要 对其销毁进行特殊的管理。
5)不能应对多线程环境:在多线程环境下,使用Singleton模式仍然有可能得到Singleton类的多个实例对象。
6、多线程单件
1)第一实现方法
public class Singleton
{
/* 关键字volatile保证严格意义的多线程不会出现微调,严格按顺序执行,
如果删除关键字volatile,编辑器有可能对代码进行微调,还是有可能出现new多次的情况*/
private static volatile Singleton _instance = null;
// 辅助器,本向不参与真正意义的构建
private static object _lockHelper = new Object();
private Singleton()
{
}
// 没有参数时使用静态属性,有参数时应使用方法GetInstance
public static Singleton Instance
{
get
{
if (_instance == null)
{
lock (_lockHelper) // 锁住_lockHelper,避免多线程的访问
{
if (instance == null)//双检查
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
// 带参数的实现如下
private int x;
private int y;
private Singleton(int x, int y)
{
this.x = x;
this.y = y;
}
public Singleton GetInstance(int x, int y)
{
if (_instance == null)
{
_instance = new Singleton(x, y);
}
else
{
_instance.x = x;
_instance.y = y;
}
return _instance;
}
}
2)第二种实现方法:不支持参数化的构造
//sealed需要不需要看实际情况
sealed class Singleton
{
//类连初始化,实际上会在静态构造器里面初始化
public static readonly Singleton Instance = new Singleton();
private int _X;
private int _Y;
private Singleton()
{
}
public void Init(FileStream fs)
{
}
public int X
{
get
{
return _X;
}
set
{
this._X = value;
}
}
public int Y
{
get
{
return _Y;
}
set
{
this._Y = value;
}
}
}
上面的方法等同于下面的方法
sealed class Singleton
{
public static readonly Singleton Instance;
//静态构造器,只在静态字段初始化前初始化
static Singleton()
{
Instance = new Singleton();
}
private Singleton()
{
}
}
class Test
{
public static void Main()
{
singleton instance = Singleton.Instance;
instance.Init(new FileStream("..."));
instance.X = 100;
instance.Y = 200;
Console.WriteLine(instance);
}
}
7、Singleton模式扩展
1)Singleton模式是对创建对象个数的控制。将一个实例扩展到n个实例,例如对象池的实现。创建n个实例放入到集合对象中,供用户使用,达到资源的有效管理。
2)将new构造的调用转移到其他类中,例如多个类协同工作环境中,某个局部环境只需要拥有某个类的一个实例。
3)理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的实例构造器的任意调用”。