此处只是个人的学习笔记,列举一些常用的设计模式,示例均来源于阎宏的java与模式,如果想更深入的学习,请看原书(本博客上有一个pdf版本的,可以去下载)
设计模式之单例
(1)饿汉式
public class EagerSingleton {
/**
* 首先new出一个私有的对象
*/
private static final EagerSingleton s_instance = new EagerSingleton();
/**
* 构造方法私有化
*/
private EagerSingleton(){};
/**
* 静态工厂方法,对外提供单一实例
* @return
*/
public static EagerSingleton getInstance(){
return s_instance;
}
}
说明:在这个类被加载时,静态变量s_instance 会被初始化,构造方法私有化,此时类的唯一对象被创建出来,以后获取都是这个实例。
(2)懒汉式
public class LazySingleton {
//单一实例
private static LazySingleton l_instance = null;
private LazySingleton(){}
//获取实例的方法
synchronized public static LazySingleton getInstance(){
if(l_instance == null){
l_instance = new LazySingleton();
}
return l_instance;
}
}
说明:此程序加载的时候不会new出实例对象,只有在getInstance方法被调用的时候才会new出对应的实例,与饿汉式的相比,此种实现开始节约了内存,但是效率不如饿汉式的高,如果方法getInstance不加synchronized 会有线程同步问题,所以在用的时候请根据各自的情况选择
(3)登记式
package com.qiao.pattern;
import java.util.HashMap;
public class RegSingleton {
static private HashMap<String,RegSingleton> m_registry = new HashMap<String,RegSingleton>();
//静态代码给map中先加载一个实例
static {
RegSingleton x = new RegSingleton();
m_registry.put(x.getClass().getName(), x);
}
protected RegSingleton(){}
static public RegSingleton getInstance(String name){
if(name == null){
name = "com.qiao.pattern.RegSingleton";//此处为你类的路径加名称
}
if(m_registry.get(name) == null){
try{
m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());
}catch(Exception e){
System.out.print("Error!");
}
}
return m_registry.get(name);
}
}
说明:由于饿汉式和懒汉式的构造子私有,所以子类无法继承,此方式子类是可以继承的。程序加载时,先new出一个map容器,此容器先加载一个单例进去,供以后调用
此种方式子类是可以继承的,下面给出一个子类的实现
package com.qiao.pattern;
public class RegSingletonChild extends RegSingleton{
public RegSingletonChild(){}
//获取实例的方法
static public RegSingletonChild getInstance(){
return (RegSingletonChild)RegSingleton.getInstance("com.qiao.pattern.RegSingletonChild");
}
}
说明,子类RegSingletonChild中的getInstance方法可以快速的获取一个自身的实例对象。缺点由于子类必须允许父类以构造方法调用产生实例,因此它的构造方法对子类必须是公开的。这样一来,就等于允许了以这样方式产生实例而不在父类的登记中。还有父类的实例必须存在才可能有子类的实例,这样有会造成一定的浪费。
下面谈谈单例模式的使用
使用单例模式有一个必要的条件:在一个系统要求一个类只有一个实例时才应当使用单例。