单列模式是设计模式中最为简单,也经常使用的一种。其主要特点是:
- 单列只有一个,对象不会被重复创建
- 单列类必须自己创建自己的唯一实例
- 单列类必须给其他所有客户端提供唯一的实例
- 构造子是私有的,从而保证该类不会被继承,严格地保证只可能产生一个实例
单列模式可以分为三个变种:饿汉式单列模式,懒汉式单列模式,登记单列模式。
1. 饿汉式单列模式
package com.patten.relin;
public class EagerSingleton {
//该类在load的时候就被创建
private static EagerSingleton m_instance = new EagerSingleton();
private EagerSingleton(){
//私有构造函数
}
public static EagerSingleton getInstance(){
return m_instance;
}
}
2. 懒汉式单列模式
package com.patten.relin;
public class LazySingleton {
private static LazySingleton m_instatnce = null;
private LazySingleton(){
}
//该类在getInstance方法第一次被调用的时候才会被初始化
synchronized public static LazySingleton getInstance(){
if(null == m_instatnce){
m_instatnce = new LazySingleton();
}
return m_instatnce;
}
}
3. 登记单列模式
父类:
package com.patten.relin;
import java.util.HashMap;
//登记式单列模市是为了克服原单列模式不可以被继承的缺点而设计的
public class RegSingleton {
private static HashMap m_registy = new HashMap();
static{
RegSingleton x = new RegSingleton();
m_registy.put(x.getClass().getName(), x);
}
//保护型构造函数,可以被子类调用
//原来两种单列模式的构造函数为私有,能够充分保证不会有其他函数调用构造函数从而产生一个以上的实列
protected RegSingleton(){
}
public static RegSingleton getInstance(String name){
if(name == null){
name = "com.patten.relin.RegSingleton";
}
if(m_registy.get(name) == null){
try {
m_registy.put(name, Class.forName(name).newInstance());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return (RegSingleton)(m_registy.get(name));
}
}
子类:
package com.patten.relin;
public class RegSingletonChild extends RegSingleton{
//构造函数必须为public才可以被父类调用,这也就违背了单列模式最初的设计,可能被无意调用从而产生多个实例
public RegSingletonChild(){
}
public static RegSingletonChild getInstance(){
return (RegSingletonChild)(RegSingleton.getInstance("com.patten.relin.RegSingletonChild"));
}
}
单列模式是可以没有状态的,因此,工具性的函数,例如Math等,特别适合使用单列模式。