单例模式

单例(Singleton)模式:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类 。

1、单例模式的要点: 

  • 某个类只能有一个实例; 
  • 它必须自行创建这个实例; 
  • 它必须自行向整个系统提供这个实例。 

 

2、单例模式的例子: 

  • 打印机; 
  • 传真机使用的传真卡,只应该由一个软件管理; 
  • Windows回收站。 

 

3、单例模式有以下特点: 

  • 单例类只能有一个实例; 
  • 单例类必须自己创建自己的唯一的实例; 
  • 单例类必须给所有其他对象提供这一实例;
  • 私有构造方法,避免外部创建实例;
  • 私有静态实例;
  • 静态工厂方法,返回此单例类唯一的实例。


4、使用单例模式的条件:

  • 使用单例模式有一个必要条件:在一个系统要求一个类只有一个实例时才应当使用单例模式,反过来说,如果一个类可以有几个实例共存,那么就没有必要使用单例模式类。 

 

 

饿汉式单例类:

public class EagerSingleton {
	private static final EagerSingleton m_instance = new EagerSingleton();

	private EagerSingleton() {
	}

	public static EagerSingleton getInstance() {
		return m_instance;
	}
}

* java语言中单例类的一个最重要的特点是类的构造方法是私有的,从而避免外界利用构造子直接创建出任意多的实例。因为构造子是私有的,因此此类不能被继承。饿汉式单例类在类加载的时候就实例化一个自己的对象。

 

懒汉式单例类:

public class LazySingleton {
	private static LazySingleton m_instance = null;

	private LazySingleton() {
	}

	synchronized public static LazySingleton getInstance() {
		if (m_instance == null) {
			m_instance = new LazySingleton();
		}
		return m_instance;
	}
}

* 与饿汉式单例类相同的是,懒汉式单例类的构造方法是私有的,不同的是在第一次被引用时才将自己实例化,如果加载器是静态的,那么在懒汉式单例类被加载时不会将自己实例化。  

 

登记式单例类:

public class RegSingleton {
	private static HashMap 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, Class.forName(name).newInstance());
			} catch (Exception e) {
				System.out.println("Error happened.");
			}
		}
		return (RegSingleton) (m_registry.get(name));
	}

	// 一个示意性的商业方法
	public String about() {
		return "Hello, I am RegSingleton";
	}
}

// 登记式单例类的子类
public class RegSingletonChild extends RegSingleton {
	public RegSingletonChild() {
	}

	// 静态工厂方法
	public static RegSingletonChild getInstance(){  
        return (RegSingletonChild)RegSingleton.getInstance("RegSingleton")  
    }
	public String about() {
		return "Hello, I am RegSingletonChild";
	}
}

* 登记式单例这个单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从工厂直接返回,对于没有登记的,则先登记,而后返回。

 

**

posted @ 2010-11-09 09:12  Mr.chenz  阅读(586)  评论(0编辑  收藏  举报