<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
    數據加載中……

    在Java中應用設計模式--Singleton

    本文介紹了設計模式中 Singleton 的基本概念,對其功能和用途進行了簡單的分析,列出了通常實現 Singleton 的幾種方法,并給出了詳細的Java 代碼.

      基本概念

      Singleton 是一種創建性模型,它用來確保只產生一個實例,并提供一個訪問它的全局訪問點.對一些類來說,保證只有一個實例是很重要的,比如有的時候,數據庫連接或 Socket 連接要受到一定的限制,必須保持同一時間只能有一個連接的存在.再舉個例子,集合中的 set 中不能包含重復的元素,添加到set里的對象必須是唯一的,如果重復的值添加到 set,它只接受一個實例.JDK中正式運用了Singleton模式來實現 set 的這一特性,大家可以查看java.util.Collections里的內部靜態類SingletonSet的原代碼.其實Singleton是最簡單但也是應用最廣泛的模式之一,在 JDK 中隨處可見.

      簡單分析

      為了實現 Singleton 模式,我們需要的是一個靜態的變量,能夠在不創建對象的情況下記憶是否已經產生過實例了.靜態變量或靜態方法都可以在不產生具體實例的情況下直接調用,這樣的變量或方法不會因為類的實例化而有所改變.在圖1的結構中可以看到,uniqueInstance 就是這個獨立的靜態變量,它可以記憶對象是否已經實例化了,在靜態方法 Instance 中對這個變量進行判斷,若沒有實例化過就產生一個新的對象,如果已經實例化了則不再產生新的對象,仍然返回以前產生的實例.


    圖1: Singleton 模式結構

      具體實施

      實現 Singleton 模式的辦法通常有三種.

      一. 用靜態方法實現 Singleton

      這種方法是使用靜態方法來監視實例的創建.為了防止創建一個以上的實例,我們最好把構造器聲明為 private.

      這樣可以防止客戶程序員通過除由我們提供的方法之外的任意方式來創建一個實例,如果不把構造器聲明為private,編譯器就會自作聰明的自動同步一個默認的friendly構造器.這種實現方法是最常見的,也就是圖1中結構的標準實現.

            public class Singleton {
                private static Singleton s; 
                private Singleton(){};
            /**
                 * Class method to access the singleton instance of the class.
             */
            public static Singleton getInstance() {
             if (s == null)
                s = new Singleton();
              return s;
            }
    }

    // 測試類
    class singletonTest {
      public static void main(String[] args) {
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        if (s1==s2)
          System.out.println("s1 is the same instance with s2");
        else
          System.out.println("s1 is not the same instance with s2");
      }
    }

      singletonTest運行結果是:
      s1 is the same instance with s2
      這證明我們只創建了一個實例.

      二. 以靜態變量為標志實現 Singleton

      在類中嵌入一個靜態變量做為標志,每次都在進入構造器的時候進行檢查.

      問題在于構造器沒有返回類型,如果確定創建一個實例成功與否.一個方法是調用一個函數來檢查創建是否成功,然后簡單的返回一個來自靜態變量的值,但是這樣做是不優雅的,而且容易發生錯誤.比較好的做法是創建一個當創建了一個以上的實例時可以拋出異常的類,這個類僅僅是調用父類方法,好處是用了自己命名的異常類型,錯誤信息更加清晰:

    class SingletonException extends RuntimeException {
      public SingletonException(String s) {
        super(s);
      }
    }

    class Singleton {
      static boolean instance_flag = false; // true if 1 instance
      public Singleton() {
        if (instance_flag)
          throw new SingletonException("Only one instance allowed");
        else
          instance_flag = true; // set flag for 1 instance
      }
    }

    // 測試類

    public class singletonTest {
      static public void main(String argv[]) {
        Singleton s1, s2;
        // create one incetance--this should always work
        System.out.println("Creating one instance");
        try {
          s1 = new Singleton();
        } catch (SingletonException e) {
          System.out.println(e.getMessage());
        }
        // try to create another spooler --should fail
        System.out.println("Creating two instance");
        try {
          s2 = new Singleton();
        } catch (SingletonException e) {
          System.out.println(e.getMessage());
        }
      }
    }

      singletonTest運行結果是:
      Creating one instance
      Creating two instance
      Only one instance allowed
      可以看出,第一個實例順利創建,第二個實例創建實拋出了我們自定義的異常.

      三. 用注冊器機制來創建 Singleton

      首先用集合中的Hashtable 和Enumeration來實現addItem(Object key, Object value),getItem(Object key), ,removeItem(Object key)等方法實現一個管理器,將key和value一一關聯起來,客戶程序員創建實例前首先用addItem方法進行注冊,再用getItem方法獲取實例.Hashtable中的key是唯一的,從而保證創建的實例是唯一的,具體實現限于篇幅不再細說,在Prototype模型的應用一文中我將會給出一個實現注冊器的代碼.用注冊器機制來創建 Singleton模式的好處是易于管理,可以同時控制多個不同類型的Singleton 實例.

      小結

      1. Singleton模式可以方便的進行擴充,產生指定數目的實例. 

      2. 在The Design Patterns Java Companion 一書中曾提到過用靜態類的方式來實現 Singleton模式,并指出java.lang.Math就是一個例子,這里我并不表示贊同,因為Math并不是一個真正的對象,我們只是直接調用Math類所包裝的靜態方法而已,根本就沒有創建實例的過程,又從何說起只產生一個實例呢?這個問題我曾到Javaranch的論壇上發過帖子,所有回帖的人也都是對這一觀點持否定態度. 

      3. 在多線程的程序中,singleton可能會變的不可靠,可能會出現多個實例,解決的辦法很簡單,加個同步修飾符: public static synchronized Singleton getInstance(). 這樣就保證了線程的安全性. 

      4. 最后要說的是大家可能會看見一些其他實現Singleton模式的方法,因為模式在具體的應用時是靈活的,不是一成不變的,并沒有一個固定的做法,但大都是上面幾種方法的變形. 

    轉自:http://www.javaresearch.org/article/showarticle.jsp?column=31&thread=28424

    posted on 2005-05-26 21:54 weidagang2046 閱讀(152) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: a级片免费在线播放| 久久WWW色情成人免费观看| 国产精品免费_区二区三区观看| 亚洲综合精品香蕉久久网97| 久久免费观看国产精品88av| 国产成人亚洲综合色影视| a视频在线观看免费| 久久久久久久综合日本亚洲 | 亚洲乱亚洲乱妇24p| 成年18网站免费视频网站| 亚洲日韩精品无码专区加勒比 | 精品视频一区二区三区免费| 狠狠色婷婷狠狠狠亚洲综合| 国产成人精品免费视频大全| 伊人婷婷综合缴情亚洲五月| 大地影院MV在线观看视频免费| 亚洲色四在线视频观看| 国产在线a免费观看| 国内成人精品亚洲日本语音 | 爱情岛论坛免费视频| 最新亚洲成av人免费看| 久久国产精品免费视频| 亚洲人妖女同在线播放| 午夜免费福利在线观看| eeuss影院www天堂免费| 亚洲人成电影在在线观看网色| 99久久99久久精品免费看蜜桃| 亚洲精品宾馆在线精品酒店| 亚洲精品国产成人影院| 99久久免费观看| 亚洲hairy多毛pics大全| 亚洲免费观看视频| 成年在线观看网站免费| 无套内谢孕妇毛片免费看看| 亚洲AV无码一区二区乱子伦| 国内自产拍自a免费毛片| 岛国岛国免费V片在线观看| 亚洲另类图片另类电影| 亚洲人成网站18禁止一区| 国产成人精品免费午夜app| 乱爱性全过程免费视频|