保证一个类仅有一个实例,并提供一个该实例的全局访问点。
1.简单的Singleton
1 //单例设计模式 这种情况不能应对多线程 2 class Singleton 3 { 4 private static Singleton instance; 5 private Singleton() { } 6 public static Singleton Instance 7 { 8 get 9 { 10 if (Instance == null) 11 { 12 instance = new Singleton(); 13 } 14 return instance; 15 } 16 } 17 }
2.应对多线程
1 //多线程 2 class ThreadSingleton 3 { 4 //不用volatile还是有可能出现多实例的产生 5 //保证特定实例不会重新排列 //可以写成方法 也可以写成属性 6 private static volatile ThreadSingleton instance = null; 7 //辅助器,不参与变化 8 private static object lockHelper = new object(); 9 private ThreadSingleton() { } 10 public static ThreadSingleton Instance 11 { 12 get 13 { 14 if (instance == null) 15 { 16 lock (lockHelper) 17 { 18 if (instance == null) 19 { 20 instance = new ThreadSingleton(); 21 } 22 } 23 } 24 return instance; 25 } 26 } 27 }
3.简单的单例模式
//另一种经典的 //只适用于无参的时候 class MSDNSingleton { public static readonly MSDNSingleton Instance = new MSDNSingleton(); //私有构造器 private MSDNSingleton { } }
解释上边的单例模式
1 class MSDNSingleton 2 { 3 //实现了内联初始化 4 public static readonly MSDNSingleton Instance; // = new MSDNSingleton(); 5 //静态的构造器 1.执行时间:如果想执行,那么一定是先执行静态构造器(BeforeFieldInit)2.如果不用就不实例化 6 //3.在多个线程下,只有一个线程执行 7 static MSDNSingleton() 8 { 9 Instance=new MSDNSingleton(); 10 } 11 //私有构造器 12 private MSDNSingleton() { } 13 }
虽然很方便,但是不支持参数化的构造器(静态构造器是不能传参数的,是系统调用的)
构造器传参数的方法用第一种和第二种,如果第三种也要实现的话,可以设计与构造器进行隔离的方法
1 //支持参数化构造器的方式 2 class ParamSingleton 3 { 4 private static ParamSingleton instance; 5 private ParamSingleton(int x, int y) 6 { 7 this.x = x; 8 this.y = y; 9 } 10 public static ParamSingleton GetInstance(int x,int y) 11 { 12 if (instance == null) 13 { 14 instance = new ParamSingleton(x, y); 15 } 16 else 17 { 18 instance.x = x; 19 instance.y = y; 20 } 21 return instance; 22 } 23 int x; 24 int y; 25 }
1 /静态构造函数不支持传参,可以设计与构造器进行隔离的方法 2 class MSDNParamSingleton 3 { 4 public readonly static MSDNParamSingleton Instance = new MSDNParamSingleton(); 5 private MSDNParamSingleton() { } 6 //与构造器进行隔离 7 int x; 8 int y; 9 public int X 10 { 11 get 12 { 13 return this.x; 14 } 15 set 16 { 17 this.X = x; 18 } 19 } 20 public int Y 21 { 22 get { return y; } 23 set { value=y;} 24 } 25 }
Singleton模式扩展
讲一个实例扩展到n个实例,例如对象池的实现
将new构造器的调用转移到其他类中,例如多个类协同工作环境中,某个局部环境只需要拥有某个类的一个实例。
理解和扩展Singleton Pattern的核心是"如何控制用户,使用new对一个类的实例构造器的任意调用"。
.NET框架中的Singleton拓展应用
MyClass c1 = new MyClass();
MyClass c2 = new MyClass();
//
Type t1 = c1.GetType();
Type t2 = c2.GetType();
推荐的好书:
重构:改善既有代码的设计 Martin Fowler
敏捷软件开发:原则 模式与实践 RobertC Martin
面向对象分析与设计 Grady booch
设计模式:可复用面向对象软件的基础 Gof
Refactoring to Patterns: joshua Kerievsky
.NET框架中的Singleton应用
Type 和HttpContext 是对应用和拓展