天天看點

java 單例模式的好處

單例模式是一種常見的設計模式,在《Java與模式》一書中,閻宏博士對單例模式做了全面的總結。

單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。

單例模式有一下特點:

1、單例類隻能有一個執行個體。

2、單例類必須自己建立自己的唯一執行個體。

3、單例類必須給所有其他對象提供這一執行個體。

說明:一下的代碼來自閻宏博士的《Java與模式》一書,其中對一些類的寫法做調整(符合Java1.5的習慣),另外還加了測試方法。

一、懶漢式單例

在類被加載的時候,唯一執行個體已經被建立。這個設計模式在Java中容易實作,在别的語言中難以實作。

/**

* Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2007-9-11

* Time: 14:57:08

* <> 單例模式-懶漢式單例

*/

public class LazySingleton {

     /**

      * 私有靜态對象,加載時候不做初始化

      */

     private static LazySingleton m_intance=null;

      * 私有構造方法,避免外部建立執行個體

     private LazySingleton(){

     }

      * 靜态工廠方法,傳回此類的唯一執行個體. 

      * 當發現執行個體沒有初始化的時候,才初始化.

      * @return LazySingleton

     synchronized public static LazySingleton getInstance(){

         if(m_intance==null){

             m_intance=new LazySingleton();

         }

         return m_intance;

}

二、餓漢式單例

在類加載的時候不建立單例執行個體。隻有在第一次請求執行個體的時候的時候建立,并且隻在第一次建立後,以後不再建立該類的執行個體。

* Time: 14:45:25

* <> 單例模式-餓漢式單例

public class EagerSingleton {

      * 私有的(private)唯一(static final)執行個體成員,在類加載的時候就建立好了單例對象

     private static final EagerSingleton m_instance = new EagerSingleton();

     private EagerSingleton() {

      * 靜态工廠方法,傳回此類的唯一執行個體.

      * @return EagerSingleton

     public static EagerSingleton getInstance() {

         return m_instance;

三、登記式單例

這個單例實際上維護的是一組單例類的執行個體,将這些執行個體存放在一個Map(登記薄)中,對于已經登記過的執行個體,則從工廠直接傳回,對于沒有登記的,則先登記,而後傳回。

* Date: 2005-9-11

* Time: 15:20:16

* <> 單例模式- 登記式單例

public class RegSingleton {

      * 登記薄,用來存放所有登記的執行個體

     private static Map m_registry = new HashMap();

     //在類加載的時候添加一個執行個體到登記薄

     static {

         RegSingleton x = new RegSingleton();

         m_registry.put(x.getClass().getName(), x);

      * 受保護的預設構造方法

     protected RegSingleton() {

      * 靜态工廠方法,傳回指定登記對象的唯一執行個體;

      * 對于已登記的直接取出傳回,對于還未登記的,先登記,然後取出傳回

      * @param name

      * @return RegSingleton

     public static RegSingleton getInstance(String name) {

         if (name == null) {

             name = "RegSingleton";

         if (m_registry.get(name) == null) {

             try {

                 m_registry.put(name, (RegSingleton) Class.forName(name).newInstance());

             } catch (InstantiationException e) {

                 e.printStackTrace();

             } catch (IllegalAccessException e) {

             } catch (ClassNotFoundException e) {

             }

         return m_registry.get(name);

      * 一個示意性的商業方法

      * @return String

     public String about() {

         return "Hello,I am RegSingleton!";