懒汉式单例
懒汉式单例类在第一次被引用时将自己实例化。这种简单实现的问题在于,每次访问getInstance()都需要同步操作,而事实上同步只在第一次访问时有意义。
public class LazySingleton {
private static LazySingleton m_intance = null;
// 私有构造方法,避免外部创建实例
private LazySingleton() {
}
// 静态工厂方法,返回此类的唯一实例.
// 当发现实例没有初始化的时候,才初始化.
// 通过synchronized关键字,同步了不同线程对getInstance()的访问。
synchronized public static LazySingleton getInstance() {
if (m_intance == null) {
m_intance = new LazySingleton();
}
return m_intance;
}
}
饿汉式单例
在类被加载时,就会将自己实例化。
public class EagerSingleton {
// 私有的(private)唯一(static final)实例成员,在类加载的时候就创建好了单例对象
private static final EagerSingleton m_instance = new EagerSingleton();
// 私有构造方法,避免外部创建实例
private EagerSingleton() {
}
// 静态工厂方法,返回此类的唯一实例.
public static EagerSingleton getInstance() {
return m_instance;
}
登记式单例
登记式单例类是GoF 为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的。
这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。
import java.util.HashMap;
import java.util.Map;
public class RegSingleton {
// 登记薄,用来存放所有登记的实例
private static Map<String, RegSingleton> m_registry = new HashMap();
//在类加载的时候添加一个实例到登记薄
static {
RegSingleton x = new RegSingleton();
m_registry.put(x.getClass().getName(), x);
}
// 受保护的默认构造方法
protected RegSingleton() {
}
// 静态工厂方法,返回指定登记对象的唯一实例;
// 对于已登记的直接取出返回,对于还未登记的,先登记,然后取出返回
public static RegSingleton getInstance(String name) {
if (name == null) {
name = "RegSingleton";
}
if (m_registry.get(name) == null) {
try {
m_registry.put(name,(RegSingleton) Class.forName(name).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return m_registry.get(name);
单例模式比喻
俺有6个漂亮的老婆,她们的老公都是我,我就是我们家里的老公Sigleton-单例模式,她们只要说道“老公”,都是指的同一个人,那就是我(刚才做了个梦啦,哪有这么好的事)。
单例模式意图
单例模式(Singleton)保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式类图
![](http://hi.csdn.net/attachment/201203/20/0_1332205375UTXt.gif)
单例模式实现
/// <summary>
/// 体现单例模式的老公类
/// </summary>
class Husband
{
private static Husband instance;
/// <summary>
/// 构造方法让其private,这就防止了外界利用new创建此类实例的可能
/// </summary>
private Husband()
{
}
/// <summary>
/// 获得本类实例的唯一全局访问点
/// </summary>
/// <returns></returns>
public static Husband CreateHusband()
{
//若实例化不存在,则new一个新实例,否则返回已有的实例
if (instance == null)
{
instance = new Husband();
}
return instance;
}
}
/// <summary>
/// 单例模式客户端应用
/// </summary>
class Program
{
static void Main(string[] args)
{
Husband h1 = Husband.CreateHusband();
Husband h2 = Husband.CreateHusband();
//我们来测试一下这两个老公是同一个人吗
if (h1 == h2)
{
Console.WriteLine("Yes!");
}
else
{
Console.WriteLine("No!");
}
Console.Read();
}
}
单例模式总结
我们的测试结果是Yes,说明老婆口中的老公就是我了!记得梦里的老公只有一个哦!该 设计模式 只需将构造函数私有,声明一个唯一全局访问点和一个私有类属性即可!