动机(Motivation)
在软件系统中,经常有这样一些特殊的类,必须保证他们在系统中只存在一个实例,才能确保他们的逻辑正确性、以及良好的效率。
如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?
这应该是设计者的责任,而不是使用者的责任。
意图(Intent)
保证一个类仅有一个实例,并提供一个该实例的全局访问点。
结构(Structure)
单线程(Singleton)模式实现:
1 class Singleton 2 { 3 private static Singleton instance= null; 4 private Singleton() 5 { } 6 7 public static Singleton GetModel() 8 { 9 if (instance== null) 10 { 11 instance= new Singleton(); 12 } 13 return instance; 14 } 15 }
多线程Singleton模式实现:
1 class SingletonMoreThread 2 {volatile多用于多线程的环境,当一个变量定义为volatile时,读取这个变量的值时候每次都是从momery里面读取而不是从cache读。
这样做是为了保证读取该变量的信息都是最新的,而无论其他线程如何更新这个变量。 3 private static volatile SingletonMoreThread instance = null; 4 private static object lockHelper = new object(); 5 private SingletonMoreThread() 6 { } 7 public static SingletonMoreThread GetModelMoreThread() 8 { 9 if (instance== null) 10 { 11 lock (lockHelper) 12 { 13 if (instance== null) 14 { 15 instance= new SingletonMoreThread(); 16 } 17 } 18 } 19 return instance; 20 } 21 }
.NET类型初始化机制下实现多线程的单例:
1 class SingletonNET 2 { 3 //解决了多线程问题,但是无法解决有参数的初始化 4 private static readonly SingletonNET instance = new SingletonNET(); 5 private SingletonNET(); 6 } 7 相当于:只能有一个线程访问静态构造器 8 class SingletonNET2 9 { 10 private static readonly SingletonNET2 instance; 11 static SingletonNET2() 12 { 13 instance = new SingletonNET2(); 14 } 15 private SingletonNET2() 16 { } 17 }
Singleton模式扩展:
将一个实例扩展到n个实例,例如对象池的实现。
将new构造器的调用转移到其他类中,例如多个类协同工作环境中,某个局部环境只需要拥有某个类的一个实例。
理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的实例构造器的任意调用”。