设计模式学习笔记之单件模式

据说设计模式起源于建筑学,后来不知道从哪年开始软件设计中也有个设计模式,总之一句话,设计模式是用来解决软件设计过程中遇到的一些问题的经过前人实际经验认证的解决方案。有一位朋友设计模式研究的很好,他告诉过我:软件中永恒不变的是变化,设计好的软件、可复用性强,易修改,易扩充的软件必须做到,发现变化,封装变化,隔离变化。其中发现变化靠的是程序设计人员的经验,封装隔离变化靠的则是像设计模式这样的类的设计原则。面向对向设计有一个原则就是“开闭原则”即对扩展开放,对修改关闭。在我学习的接触过的设计模式中深深的感觉到设计模式的的基本原则也就是这样,一般都是为软件的变化和扩展服务的,突出面向接口编程,如果修改,对其按照一定的接口扩展,不去修改它原来的程序。下面就从一个最简单的设计模式单件记起:
一,单件模式
1)程序示例
当一系统中一个类只需要有一个实例对象的时候,可以用单件模式来解决问题,看下面一段程序

using System;
public  class Test
{
 public static void Main()
 {
  Singleton.Instance.OutPut("this  is a Singleton Design Pattern!");
  Console.ReadLine();
 }
}
public   class Singleton
{
 private static Singleton instance;
 public static Singleton Instance
 {
  get{
   if(instance==null)
   {
      instance=new Singleton();
   }
   return instance;
  
  }  
 }
private Singleton()
 {
 }
 public  void OutPut(string sentence)
 {
  Console.WriteLine(sentence);
 }
}
2)解释
这就是模式最简单的实现,首先看一下单件这个类,首先这个类的构造函数是私有的,这就避免了外界实例化它(即new一个新的实例),那么它怎么用这个类呢,看看这个类有个静态只读属性Instance,它返回私有静态变量instance,当首次访问这个类的时候,instance一定是空,那么它就调用本类的构造函数(是本类的呀,能调用了吧,呵呵!),初始化一个本类的实例,即便构造函数里什么都没有(什么都没有也不能不写,因为这是为了屏避公有的默认构造函数),当然跟据程序的需要这里面可以写东西的。同于静态变量在程序整个运行过程中只有一个,所以下次再访问该类的时候instance不为Null,返回的始终是一次创建的本类实例,外界不能对此类进行实例化,通过访问静态方法得到本类唯一实例,在整个程序运行的过程中只有一个实例,这就是单件模式。
3)存在的问题与改进
大家思考一上面的程序如果是一多个线程同时进入访问这个类的公有属性呢?if(instance==null),这时候不能够保证该类只有一个实例了,那么怎么办呢?答案是可以例用线程锁定来解决这个问题,在lock块内只允许一个线程访问,这样就解决了多线程访问出现不能保证一个实例的问题,部分代码如下:
private static object _helper = new object();
private static Singleton instance = new Singleton();
public static Singleton Instance
 {
  get{
    lock(_helper)
    {
     if(instance==null)
     {
        instance=new Singleton();
     }
   }
   return instance ;
 }   
 }
同一时刻只允许一个线程访问Lock块,其它线程只能够在后面排着,等到前一个线程执行出lock块后,下一个线程才能够被锁定,进入lock块,并且每一个线程都要被锁定。想一想这样会什么后果呢?对了,就是太浪费系统资源了,太浪费时间了。为了解决这个问题,我们伟大的设计模式先驱者提出了双重判断(double check)来解决这个问题,代码如下:
private static object _helper = new object();
private static Singleton instance = new Singleton();
public static Singleton Instance
 {
  get{
   if(instance == null)//在这里增加一层判断
   {
    lock(_helper)
    {
     if(instance==null)
     {
        instance=new Singleton();
     }
    }
   }
   return instance ;
 }   
 }

跟据上面的一行注释可以看到我们加的一层判断了,只有当第一个线程的时候才锁定了线程,后面的线程再进来的时候instance就不为null了,直接返回了唯一的实例.至此一个单件模式到这里就很完善了。
4)用途:
这个模式用途很多了,就拿大家比较熟悉的word来说吧,带菜单的窗体只有一个....
5)疑问:静态类能够代替单件模式吗?
刚才说完了单件模式在整个运行过程中只能有一个实例,那么用静态类不是一样吗?我也有过这样的疑问,后来还是请教了高人,呵呵,如果当类做为一个方法的参数的时候,静态类怎么做参数呢,答案是不可能的,所以有些时候静态类是不能取代单件模式的。

 

你可能感兴趣的:(设计模式)