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

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

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

    無為

    無為則可為,無為則至深!

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks
    本文介紹了設(shè)計(jì)模式中?Singleton?的基本概念,對(duì)其功能和用途進(jìn)行了簡(jiǎn)單的分析,列出了通常實(shí)現(xiàn)?Singleton?的幾種方法,并給出了詳細(xì)的Java?代碼.?

      基本概念

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

      簡(jiǎn)單分析

      為了實(shí)現(xiàn)?Singleton?模式,我們需要的是一個(gè)靜態(tài)的變量,能夠在不創(chuàng)建對(duì)象的情況下記憶是否已經(jīng)產(chǎn)生過實(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)行判斷,若沒有實(shí)例化過就產(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)方法來監(jiān)視實(shí)例的創(chuàng)建.為了防止創(chuàng)建一個(gè)以上的實(shí)例,我們最好把構(gòu)造器聲明為?private.

      這樣可以防止客戶程序員通過除由我們提供的方法之外的任意方式來創(chuàng)建一個(gè)實(shí)例,如果不把構(gòu)造器聲明為private,編譯器就會(huì)自作聰明的自動(dòng)同步一個(gè)默認(rèn)的friendly構(gòu)造器.這種實(shí)現(xià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)行檢查.

      問題在于構(gòu)造器沒有返回類型,如果確定創(chuàng)建一個(gè)實(shí)例成功與否.一個(gè)方法是調(diào)用一個(gè)函數(shù)來檢查創(chuàng)建是否成功,然后簡(jiǎn)單的返回一個(gè)來自靜態(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ī)制來創(chuàng)建?Singleton

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

      小結(jié)

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

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

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

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


    凡是有該標(biāo)志的文章,都是該blog博主Caoer(草兒)原創(chuàng),凡是索引、收藏
    、轉(zhuǎn)載請(qǐng)注明來處和原文作者。非常感謝。

    posted on 2006-06-11 12:57 草兒 閱讀(242) 評(píng)論(0)  編輯  收藏 所屬分類: Java編程經(jīng)驗(yàn)談模式識(shí)別
    主站蜘蛛池模板: 美女视频黄频a免费观看| 无码国模国产在线观看免费 | 4444www免费看| 一级一级毛片免费播放| 亚洲人成人伊人成综合网无码| 亚洲va在线va天堂va888www| 亚洲国产午夜中文字幕精品黄网站| 成人超污免费网站在线看| 亚洲免费福利视频| 免费人成视频在线观看网站 | 亚洲天堂在线视频| 亚洲高清视频一视频二视频三| 免费看国产精品3a黄的视频| 蜜臀AV免费一区二区三区| 日本中文字幕免费高清视频| 9i9精品国产免费久久| 成人在线免费视频| 免费人妻精品一区二区三区| 激情小说亚洲色图| 国产精品久久久久久亚洲影视| 亚洲中文无码亚洲人成影院| 久久亚洲精品专区蓝色区| 亚洲一级大黄大色毛片| 国产精品久久亚洲不卡动漫| 亚洲另类古典武侠| 亚洲一级片在线播放| 亚洲va精品中文字幕| 亚洲AV无码久久久久网站蜜桃 | 欧美大尺寸SUV免费| 在线播放免费播放av片| 国外成人免费高清激情视频| 午夜成年女人毛片免费观看| 最新69国产成人精品免费视频动漫| 久久电影网午夜鲁丝片免费| 噜噜嘿在线视频免费观看| 麻豆国产精品入口免费观看| 日本免费一区二区三区最新| 免费**毛片在线播放直播| 亚洲美日韩Av中文字幕无码久久久妻妇| 亚洲国产高清在线一区二区三区| 国产成人精品曰本亚洲79ren|