设计模式 Singleton

  设计模式 Singleton 收藏

 


类别:创建型
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
适用:
当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
----------------------

单件和工厂估计是最常用的设计模式了,想必每个人都很熟。本贴只是研究一些 Singleton 的"变种"。

1. 通用泛型单件模式

class ClassA
{
}

class ClassB
{
}

public static class Singleton<T>
  where T : class, new()
{
  private static T instance;

  public static T Instance
  {
    get
    {
      if (instance == null)
        instance = new T();

      return instance;
    }
  }
}

public class Program
{
  static void Main(string[] args)
  {
    ClassA a1 = Singleton<ClassA>.Instance;
    ClassA a2 = Singleton<ClassA>.Instance;
    Console.WriteLine(object.ReferenceEquals(a1, a2)); // output: true

    ClassB b1 = Singleton<ClassB>.Instance;
    Console.WriteLine(object.ReferenceEquals(a1, b1)); // output: false
  }
}

该方式的好处是:
(1) 支持已有类型
(2) 支持多类型
(3) 无需修改目标类型,用户可以在单件和多实例之间自由选择。

2. 线程安全

大多数单件模式的例子(包括上面的)并没有做线程安全处理,因此在执行 "new Instance()" 时存在一定的隐患。

方式1:Lock
public static class Singleton<T>
  where T : class, new()
{
  private static T instance;
  private static object o = new object();

  public static T Instance
  {
    get
    {
      if (instance == null)
      {
        lock (o)
        {
          if (instance == null)
            instance = new T();
        }
      }

      return instance;
    }
  }
}

注意使用了两次 "instance == null" 判断。因为可能有两个以上的线程进入第一个判断语句,其中一些在 lock 释放后有可能再次执行 "new T()" 操作,因此加上第二个判断避免这种情况发生。

方式2:嵌套类静态构造
public static class Singleton<T>
  where T : class, new()
{
  public static T Instance
  {
    get
    {
      return Nested.instance;
    }
  }

  private class Nested
  {
    internal static T instance = new T();
  }
}

我们知道无论如何,静态构造只会被执行一次,因此自然也就是多线程安全的了。只所以使用嵌套类是因为在需要的时候才初始化该实例,另外不用对外公开这些细节。

另外,需要补充说明的是:

泛型类声明中的静态变量在相同封闭构造类型的所有实例之间共享,但是不会在不同封闭构造类型的实例之间共享。不管静态变量的类型是否涉及任何类型参数,这些规则都适用。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yifan268/archive/2007/03/21/1536884.aspx

posted on 2010-01-29 11:49  蜗牛与老鹰  阅读(227)  评论(0编辑  收藏  举报

导航