細(xì)心!用心!耐心!

          吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學(xué)業(yè),五六點(diǎn)粗墨,七八筆買賣,九十道人情。

          BlogJava 聯(lián)系 聚合 管理
            1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
          考慮使用 Singleton 模式 時擁有子類別的問題,在Singleton模式中的getInstance()通常是一個靜態(tài)方法,不能在子類別中重新定義它,關(guān)於子類別實(shí)例的產(chǎn)生交由getInstance()來進(jìn)行是最好的選擇,例如:
          public class Singleton {
              private static Singleton instance = null;
              private Singleton() {
                  // ....
              }

              public static Singleton getInstance() {
                  if (instance == null) {
                      // getEnv表示系統(tǒng)環(huán)境變數(shù)
                      String style = getEnv("style");

                      if (style.equals("child1"))
                          instance = new ChildSingleton1();
                      else if (style.equals("child2r"))
                          instance = new ChildSingleton2();
                      else
                          instance = new Singleton();
                  }

                  return _instance;
              }

              // ....
          }

          上面這個程式片段改寫自 Gof 書中關(guān)於Singleton的例子,並用Java實(shí)現(xiàn);在書中指出,這個例子的缺點(diǎn)是每增加一個子類別,getInstance()就必須重新修改,這個問題在Java中可以使用Reflection機(jī)制來解決:
          public class Singleton {
              private static Singleton instance = null;
              private Singleton() {
                  // ....
              }

              public static Singleton getInstance() {
                  if (instance == null) {
                      // getEnv表示環(huán)境變數(shù)
                      String style = getEnv("style");

                      try {
                          instance = (Singleton)
                                    Class.forName(style).newInstance();
                      }
                      catch(Exception e) {
                          System.out.println(
                             "Sorry! No such class defined!");
                      }
                  }

                  return instance;
              }

              // ....
          }

          上面的方式使用了Java的Reflection機(jī)制,並透過環(huán)境變數(shù)設(shè)定要產(chǎn)生的子類Singleton,如果不使用Reflection的話,Gof 書中提出的改進(jìn)方法是使用Registry of Singleton方法:
          import java.util.*;

          public class Singleton {
              // 註冊表,用於註冊子類別物件
              private static Map registry = new HashMap();
              private static Singleton instance;

              public static void register(
                           String name, Singleton singleton) {
                  registry.put(name, singleton);
              }

              public static Singleton getInstance() {
                  if (instance == null) {
                      // getEnv表示取得環(huán)境變數(shù)
                      String style = getEnv("style");
                      instance = lookup(style);
                  }

                  return instance;
              }

              protected static Singleton lookup(String name) {
                  return (Singleton) registry.get(name);
              }
          }

          在Gof書中使用List來實(shí)現(xiàn)註冊表,而在這邊使用HasMap類別來實(shí)現(xiàn),它是由Java SE所提供的;在父類別中提供一個register() 以註冊Singleton的子類別所產(chǎn)生之實(shí)例,而註冊的時機(jī)可以放在子類別的建構(gòu)方法中加以實(shí)現(xiàn),例如:
          public class ChildSingleton1 extends Singleton {
              public ChildSingleton1() {
                  // ....
                  // 註冊子類別物件
                  register(getClass().getName(), this); 
              }
          }
           
          若要利用Singleton,則先使用這個子類別產(chǎn)生物件,這會向父類別註冊物件,之後透過Singleton父類別來取得物件:
          // 必須先啟始這段註冊程序
          // 產(chǎn)生並註冊ChildSingleton1物件
          new ChildSingleton1();
          // 產(chǎn)生並註冊ChildSingleton2物件
          new ChildSingleton2();

          // 註冊完成,可以使用父類別來取得子類的Singleton
          // 至於取回何哪一個,視您的環(huán)境變數(shù)設(shè)置決定
          Singleton childSingleton = Singleton.getInstance();
           

          這種方式的缺點(diǎn)是您必須在程式中啟始一段程序,先向父類別註冊子類的Singleton,之後才能透過父類別來取得指定的子類別Singleton實(shí)例,好處是可以適用於沒有Reflection機(jī)制的語言,如果您想要改變Singleton父類傳回的子類Singleton,可以在上面的 Singleton類別中加入一個reset()方法,將instance設(shè)定為null,然後重新設(shè)定環(huán)境變數(shù),之後再利用 Singleton父類的getInstance()方法重新取得註冊表中的其它子類。

          事實(shí)上Registry of Singleton的真正優(yōu)點(diǎn)正在於此,您可以使用父類別來統(tǒng)一管理多個繼承的子類別之Singleton實(shí)例,您可以在需要的時候再向父類別註冊子類 Singleton,必要時隨時調(diào)整傳回的子類別Singleton。
          posted on 2007-04-17 10:33 張金鵬 閱讀(395) 評論(1)  編輯  收藏 所屬分類: Creational 模式

          Feedback

          # re: Design Pattern: Registry of Singleton 模式[未登錄] 2012-03-19 21:43 nathan
          可惜子類的構(gòu)造函數(shù)是public的  回復(fù)  更多評論
            

          主站蜘蛛池模板: 义马市| 乌苏市| 微博| 元朗区| 宜州市| 呼图壁县| 天水市| 宁乡县| 墨竹工卡县| 南昌县| 德格县| 定襄县| 朔州市| 林甸县| 潞城市| 广宗县| 龙游县| 鞍山市| 东城区| 曲靖市| 远安县| 禹城市| 金平| 东安县| 阳高县| 安化县| 大田县| 华坪县| 巫山县| 泊头市| 揭东县| 葵青区| 永修县| 临桂县| 清徐县| 福州市| 涟源市| 五指山市| 芒康县| 平陆县| 青龙|