单例模式

举例:一些资源管理器常常设计成单例模式。例如每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个两个打印作业同时输出到打印机上;每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求调用;我们的电脑,在整个视窗系统中,回收站只能有一个实例,因此回收站也是单例模式的应用。

单例模式的特点:
1.单例类只能有一个实例。
2.单例类必须自己创建自己的唯一的实例。
3.单例类必须给所有其他对象提供这一实例(public)。 

饿汉式单例类:

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;

          }

}

饿汉式与懒汉式对比:
饿汉式单例类在自己被加载时就将自己实例化。即便加载器是静态的,在饿汉式单例类被加载时仍会将自己实例化。单从资源利用效率来讲,饿汉式比懒汉式稍差些。从速度和反应时间来讲,饿汉式比懒汉式单例类稍好些。 

登记式单例类:
登记式单例类是GoF为了克服饿汉式及懒汉式均不可继承的缺点而设计的。

 

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与模式》。

 

 

posted on 2013-04-14 12:07  屎先生的奇幻漂流  阅读(131)  评论(0编辑  收藏  举报

导航