C#设计模式之4——单件模式

来源:互联网 发布:sas数据分析 编辑:程序博客网 时间:2024/04/30 10:39

1. 简单工厂模式:http://blog.csdn.net/weixingstudio/article/details/7234423

2. 工厂方法模式:http://blog.csdn.net/weixingstudio/article/details/7234700

3. 抽象工厂模式:http://blog.csdn.net/weixingstudio/article/details/7246254

 

单件模式(Singleton)在某种程度上来说是限制而不是促进类的创建。单件模式确保类有且仅有一个实例,并提供了一个对该实例的全局访问点。在实际程序中,有很多类是需要确保有且仅有一个实例的。

 

1. 使用静态方法创建单件

 

使得类只能有一个实例的最简单的方法就是在类中包含一个静态变量,因为静态变量默认的为类变量,为所有的类实例所共有,该变量在第一个实例生成时候进行设定,然后每次进入该构造函数的时候检查这个变量,静态变量用来指示一个实例,为了防止对类的实例化超过一次,我们可以把类的构造函数设为私有的,这样实例就只能通过类的静态方法在类的内部创建。 私有构造函数规定了类的实例化只能在类的内部进行。

 

如下面的示例:

using System;namespace GlobalSpooler{/// <summary>/// Summary description for Spooler./// </summary>public class Spooler {private static bool instance_flag= false;private Spooler()  {}public static Spooler getSpooler() {if (! instance_flag) return new Spooler ();elsereturn null;}}}


然后就可以根据返回的是否为null来进行操作:

 

using System;namespace GlobalSpooler{/// <summary>/// Summary description for Class1./// </summary>class GlobSpooler{static void Main(string[] args) {Spooler sp1 = Spooler.getSpooler();if (sp1 != null)Console.WriteLine ("Got 1 spooler");Spooler sp2 = Spooler.getSpooler ();if (sp2 == null)Console.WriteLine ("Can\'t get spooler");//fails at compile timeSpooler sp3 = new Spooler ();}}}


这里如果直接创建对象实例就会失败,因为没有共有的构造函数可以调用。上面的程序也可以很容易的修改为支持指定个数的实例存在的程序。

 

2. 异常与实例

 

上面方法的缺点是需要开发者自己判断返回值是否为null,但是我们不能确定开发者是否进行判断,这样就会可能为接下来的开发造成灾难。我们创建一个自己的异常类,如果编程者试图对该类实例化超过一次,就返回一个异常。这样更有益于错误的控制。

异常类如下:

 

using System;namespace singleSpooler{/// <summary>/// Summary description for SingletonException./// </summary>public class SingletonException:Exception{//new exception type for singleton classespublic SingletonException(string s):base(s) {}}}


 

3.抛出异常

 

抛出异常的代码类如下:

 

using System;namespace singleSpooler{/// <summary>/// Prototype of Spooler Singleton/// such that only one instane can ever exist./// </summary>public class Spooler {static bool instance_flag = false; //true if one instancepublic Spooler()  {if (instance_flag)throw new SingletonException("Only one printer allowed");elseinstance_flag=true;     //set flag for one instanceConsole.WriteLine ("printer opened");    }}}


 

如果已经实例化过了,我们的类再次创建实例的时候就会抛出异常。

 

4. 创建类的一个实例。

单间模式的简单使用方法如下:

using System;namespace singleSpooler{/// <summary>/// Summary description for Class1./// </summary>public class singleSpooler {static void Main(string[] args) { Spooler pr1, pr2;      //open one printer--this should always work      Console.WriteLine ("Opening one spooler");      try {pr1 = new Spooler();      }      catch (SingletonException e){  Console.WriteLine (e.Message);  }      //try to open another printer --should fail      Console.WriteLine ("Opening two spoolers");      try{      pr2 = new Spooler();      }      catch (SingletonException e) {  Console.WriteLine (e.Message);  }}}}


5. 提供到单件的全局访问点。

最常见的提供全局访问点的方法就是使用类的静态方法,因为类的名称始终是可用的,静态方法只能通过类名而不是类的实例进行调用。

 

最后,说明一下,单件模式更多的使用的是类的私有构造函数,这样类的实例化只能在类的内部进行,同时,还有一种方法保证单件模式:就是在类的内部有私有构造函数,而且还有静态构造函数,在静态构造函数中可以调用私有构造函数在类的内部实例化对象,然而类的静态构造函数只能是在类进行第一次调用的时候才被调用,而且只被调用一次,这样就保证了只有一个类的实例。

 

原创粉丝点击