设计模式之单例
所谓单例必须满足
1.一个类只能有一个实例
2.实例只能由自己去创建
3.必须自行提供实例
单例可以分为饿汉式、懒汉式、注册式单例
下面是饿汉式单例模式的代码:
public class Singleton {//定义唯一实例并初始化private static final Singleton instance=new Singleton();//私有构造器防止外部通过new实例化private Singleton(){}//向全局提供唯一实例public static Singleton getInstance(){return instance;}}
?
备注:该类在加载时会调用私有构造器初始化唯一实例,另外构造器是私有的因而不能被继承。
下面是懒汉式单例模式的代码:
public class Singleton {//定义唯一实例private static Singleton instance=null;//私有构造器private Singleton(){}/** * 加载类(静态加载器)的时候并没有初始化实例 * 而是在调用的时候才初始化实例 * 因而称为懒汉式单例 * 用synchronized关键字防止 * 同时多个线程调用创建多个实例 */public synchronized Singleton getInstance(){if(null==instance)instance=new Singleton();return instance;}}
?备注:该类在加载时会调用私有构造器初始化唯一实例,另外构造器是私有的因而不能被继承。
注册式单例类是为了克服饿汉、懒汉式单例不能被继承的缺点而设计的。
public class Singleton {//定义唯一实例private static HashMap m_instance=new HashMap();static {Singleton s=new Singleton();m_instance.put(s.getClass().getName(), s);}//保护的构造器protected Singleton(){}public static Singleton getInstance(String name){ if(name==null){ name="Singleton"; } //如果hashmap中没有该单例类,则将其添加进去 if(!m_instance.containsKey(name)){try{ //利用Java反射机制动态实例化该单例类m_instance.put(name, Class.forName(name).newInstance());} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} } return (Singleton)m_instance.get(name); }}
?下面子类化该注册式单例类
public class SingletonChild extends Singleton {public SingletonChild(){}/** * 静态工厂方法 */public static SingletonChild getInstance(){return (SingletonChild)Singleton.getInstance("SingletonChild");}}
?
因为子类要继承父类,因此父类构造器必须是公开的。这样就有可能直接通过new来产生单例类而不通过父类的注册,这是注册式单例类的一个缺点.
?
?
?