创建型模式:Singleton单件

                                                                     创建型模式:Singleton单件
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对一个类的实例构造器的任意调用”。

你可能感兴趣的:(创建型模式:Singleton单件)