单件和工厂可能是设计模式中最基础,最好理解的部分了。下面说的是 .net 中一些单件模式中的东西。
单件模式是实现程序中只有一个某个类型的实例。最简单的代码应该如下:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Class1
{
private Class1() { }
private static Class1 instance;
public static Class1 Instance
{
get
{
if (instance == null)
{
instance = new Class1();
}
return instance;
}
}
}
}
但是,这在多线程的情况下,还是有可能产生多个实例的。如有加个锁,可以防止产生多个实例:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Class1
{
private Class1() { }
private static volatile Class1 instance;
private static object locker = new object();
public static Class1 Instance
{
get
{
if (instance == null)
{
lock (locker)
{
instance = new Class1();
}
}
return instance;
}
}
}
}
这里的 volatile 可以保证在多线程环境下,变量的值总是最新的。compiler 不会假定它是处于单线程访问环境下。
但是,这样写也有一点麻烦。看了 MSDN 的 Webcast 之后,人家给出了另一种方法:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Class1
{
private Class1() { }
private static readonly Class1 instance = new Class1();
public static Class1 Instance
{
get
{
return instance;
}
}
}
}
由于编译器只会以单线程使用静态构造函数,所以这样做可以保证在多线程下的安全性。
如果要实现参数化的单件模式,上面的 readonly 方法做起来会有一点麻烦。下面是 readonly 方法下的参数化单件模式的实现:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Class1
{
private Class1() { }
private string str = "";
private static readonly Class1 instance = new Class1();
public static Class1 GetInstance(string s)
{
instance.Initialize(s);
return instance;
}
private void Initialize(string s)
{
this.str = s;
}
}
}当然还可以用私有的参数化构造函数来做,效果一样。如果用 lock 的话,代码量无疑会多一些。webcast 的讲师说得对,简单就是美

