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

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

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

    隨筆 - 8  文章 - 55  trackbacks - 0
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(6)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    朋友的Blog

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    在Java中應(yīng)用設(shè)計(jì)模式--Singleton

    作者:劉湛    來(lái)自:IBM

      本文介紹了設(shè)計(jì)模式中 Singleton 的基本概念,對(duì)其功能和用途進(jìn)行了簡(jiǎn)單的分析,列出了通常實(shí)現(xiàn) Singleton 的幾種方法,并給出了詳細(xì)的Java 代碼.

      基本概念

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

      簡(jiǎn)單分析

      為了實(shí)現(xiàn) Singleton 模式,我們需要的是一個(gè)靜態(tài)的變量,能夠在不創(chuàng)建對(duì)象的情況下記憶是否已經(jīng)產(chǎn)生過(guò)實(shí)例了.靜態(tài)變量或靜態(tài)方法都可以在不產(chǎn)生具體實(shí)例的情況下直接調(diào)用,這樣的變量或方法不會(huì)因?yàn)轭惖膶?shí)例化而有所改變.在圖1的結(jié)構(gòu)中可以看到,uniqueInstance 就是這個(gè)獨(dú)立的靜態(tài)變量,它可以記憶對(duì)象是否已經(jīng)實(shí)例化了,在靜態(tài)方法 Instance 中對(duì)這個(gè)變量進(jìn)行判斷,若沒(méi)有實(shí)例化過(guò)就產(chǎn)生一個(gè)新的對(duì)象,如果已經(jīng)實(shí)例化了則不再產(chǎn)生新的對(duì)象,仍然返回以前產(chǎn)生的實(shí)例.


    圖1: Singleton 模式結(jié)構(gòu)

      具體實(shí)施

      實(shí)現(xiàn) Singleton 模式的辦法通常有三種.

      一. 用靜態(tài)方法實(shí)現(xiàn) Singleton

      這種方法是使用靜態(tài)方法來(lái)監(jiān)視實(shí)例的創(chuàng)建.為了防止創(chuàng)建一個(gè)以上的實(shí)例,我們最好把構(gòu)造器聲明為 private.

      這樣可以防止客戶程序員通過(guò)除由我們提供的方法之外的任意方式來(lái)創(chuàng)建一個(gè)實(shí)例,如果不把構(gòu)造器聲明為private,編譯器就會(huì)自作聰明的自動(dòng)同步一個(gè)默認(rèn)的friendly構(gòu)造器.這種實(shí)現(xiàn)方法是最常見(jiàn)的,也就是圖1中結(jié)構(gòu)的標(biāo)準(zhǔn)實(shí)現(xiàn).

            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;
            }
    }

    // 測(cè)試類
    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運(yùn)行結(jié)果是:
      s1 is the same instance with s2
      這證明我們只創(chuàng)建了一個(gè)實(shí)例.

      二. 以靜態(tài)變量為標(biāo)志實(shí)現(xiàn) Singleton

      在類中嵌入一個(gè)靜態(tài)變量做為標(biāo)志,每次都在進(jìn)入構(gòu)造器的時(shí)候進(jìn)行檢查.

      問(wèn)題在于構(gòu)造器沒(méi)有返回類型,如果確定創(chuàng)建一個(gè)實(shí)例成功與否.一個(gè)方法是調(diào)用一個(gè)函數(shù)來(lái)檢查創(chuàng)建是否成功,然后簡(jiǎn)單的返回一個(gè)來(lái)自靜態(tài)變量的值,但是這樣做是不優(yōu)雅的,而且容易發(fā)生錯(cuò)誤.比較好的做法是創(chuàng)建一個(gè)當(dāng)創(chuàng)建了一個(gè)以上的實(shí)例時(shí)可以拋出異常的類,這個(gè)類僅僅是調(diào)用父類方法,好處是用了自己命名的異常類型,錯(cuò)誤信息更加清晰:

    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
      }
    }

    // 測(cè)試類

    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運(yùn)行結(jié)果是:
      Creating one instance
      Creating two instance
      Only one instance allowed
      可以看出,第一個(gè)實(shí)例順利創(chuàng)建,第二個(gè)實(shí)例創(chuàng)建實(shí)拋出了我們自定義的異常.

      三. 用注冊(cè)器機(jī)制來(lái)創(chuàng)建 Singleton

      首先用集合中的Hashtable 和Enumeration來(lái)實(shí)現(xiàn)addItem(Object key, Object value),getItem(Object key), ,removeItem(Object key)等方法實(shí)現(xiàn)一個(gè)管理器,將key和value一一關(guān)聯(lián)起來(lái),客戶程序員創(chuàng)建實(shí)例前首先用addItem方法進(jìn)行注冊(cè),再用getItem方法獲取實(shí)例.Hashtable中的key是唯一的,從而保證創(chuàng)建的實(shí)例是唯一的,具體實(shí)現(xiàn)限于篇幅不再細(xì)說(shuō),在Prototype模型的應(yīng)用一文中我將會(huì)給出一個(gè)實(shí)現(xiàn)注冊(cè)器的代碼.用注冊(cè)器機(jī)制來(lái)創(chuàng)建 Singleton模式的好處是易于管理,可以同時(shí)控制多個(gè)不同類型的Singleton 實(shí)例.

      小結(jié)

      1. Singleton模式可以方便的進(jìn)行擴(kuò)充,產(chǎn)生指定數(shù)目的實(shí)例.

      2. 在The Design Patterns Java Companion 一書(shū)中曾提到過(guò)用靜態(tài)類的方式來(lái)實(shí)現(xiàn) Singleton模式,并指出java.lang.Math就是一個(gè)例子,這里我并不表示贊同,因?yàn)镸ath并不是一個(gè)真正的對(duì)象,我們只是直接調(diào)用Math類所包裝的靜態(tài)方法而已,根本就沒(méi)有創(chuàng)建實(shí)例的過(guò)程,又從何說(shuō)起只產(chǎn)生一個(gè)實(shí)例呢?這個(gè)問(wèn)題我曾到Javaranch的論壇上發(fā)過(guò)帖子,所有回帖的人也都是對(duì)這一觀點(diǎn)持否定態(tài)度.

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

      4. 最后要說(shuō)的是大家可能會(huì)看見(jiàn)一些其他實(shí)現(xiàn)Singleton模式的方法,因?yàn)槟J皆诰唧w的應(yīng)用時(shí)是靈活的,不是一成不變的,并沒(méi)有一個(gè)固定的做法,但大都是上面幾種方法的變形.

    posted on 2006-05-18 16:08 blog搬家了--[www.ialway.com/blog] 閱讀(204) 評(píng)論(0)  編輯  收藏 所屬分類: Java
    主站蜘蛛池模板: 亚洲国产综合精品中文字幕 | 少妇高潮太爽了在线观看免费| 亚洲性一级理论片在线观看| 成年女人喷潮毛片免费播放| 免费国产va在线观看| 亚洲A∨无码一区二区三区| 国产成人免费高清激情明星| 色www免费视频| 亚洲资源在线观看| 亚洲人成网站18禁止久久影院| 嫩草影院在线免费观看| 91视频免费观看高清观看完整| 亚洲欧洲国产精品香蕉网| 免费黄色网址网站| 国产A∨免费精品视频| 亚洲人成片在线观看| 亚洲精品无码专区2| 久久不见久久见中文字幕免费| XXX2高清在线观看免费视频| 亚洲一卡2卡3卡4卡乱码 在线| 亚洲色偷偷偷鲁综合| 女人张开腿等男人桶免费视频| 丁香花在线视频观看免费| 亚洲AV无码成人精品区日韩| 亚洲国产老鸭窝一区二区三区| 成人永久免费福利视频网站| 最近免费中文字幕高清大全| 亚洲视频在线免费| 亚洲精品国产摄像头| 亚洲视频在线免费看| 国产亚洲美女精品久久久2020| 国产免费变态视频网址网站| 国产又大又粗又长免费视频| 在线涩涩免费观看国产精品| 另类图片亚洲校园小说区| 亚洲永久在线观看| 亚洲国产综合精品| 亚洲AV无码精品色午夜果冻不卡| 亚洲福利精品一区二区三区 | 亚洲成av人片在线观看天堂无码| 无码人妻一区二区三区免费手机 |