举例:一些资源管理器常常设计成单例模式。例如每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个两个打印作业同时输出到打印机上;每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求调用;我们的电脑,在整个视窗系统中,回收站只能有一个实例,因此回收站也是单例模式的应用。
饿汉式单例类:
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; } }
import java.util.HashMap; public class RegSingleton{ static private HashMap m_registry = new HashMap(); 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.javapatterns.singleton.demos.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"; } }
它的子类RegSingletonChild需要父类的帮助才能实例化。
import java.util.HashMap; public class RegSingletonChild extends RegSingleton{ public RegSingletonChild(){} //静态工厂方法 static public RegSingletonChild getInstance(){ renturn (RegSingletonChild)RegSingleton.getInstance( "com.javapatterns.singleton.demos.RegSingletonChild"); } //一个示意性的商业方法 public String about(){ return "Hello , I am RegSingletonChild"; } }
以上内容整理自《JAVA与模式》。