A Cooly Weblog

             ::  ::  ::  ::  :: 管理

          單例模式Singleton

          Posted on 2007-02-22 18:48 acooly 閱讀(426) 評論(0)  編輯  收藏 所屬分類: Java開發設計模式

          ??????單例模式(singleton)在很多系統中都比較常用。我用得最多的就是用來做緩存。最新重新學習設計模式,想整理一下開發中的一些經驗和資料上的講解以備以后查看。

          Singleton模式要點
          1.單例類在一個容器中只有一個實例。
          2.單例類使用靜態方法自己提供向客戶端提供實例,自己擁有自己的引用。
          3.必須向整個容器提供自己的實例。

          單例類的狀態
          1、無狀態單例類可以在多個容器或JVM中存在多個實例而正常運行,因為它是無狀態就意味是完全相同的拷貝,如系統內的通用工具方法類等;
          2、有狀態的單例實例一般是可變的,比如提供表的為一KEY的單例類,一般不在多個容器或JVM中使用,除非建立特殊機制協調各個實例間的狀態。

          單例類的種類
          1、餓漢式和懶漢式
          餓漢式和懶漢式單例非常相識,主要的區別在于餓漢式在聲明實例變量的時候就初始化實例,而懶漢式是在構造函數中通過判斷實例是否存在,在創建實例。

          /*
          ?*?餓漢是單例類?Hungry?Singleton
          ?@author?ZhangPu
          ?Feb?22,?2007?7:34:50?PM
          ?
          */


          public ? class ?HungrySingleton? {
          ????
          /** ?聲明時候初始化? */
          ????
          private ? static ?HungrySingleton?hungrySingleton? = ? new ?HungrySingleton();
          ????
          /**
          ?????*?私有構造
          ?????
          */

          ????
          private ?HungrySingleton() {}
          ????
          ????
          /**
          ?????*?單例方法
          ?????*?
          @return
          ?????
          */

          ????
          public ? static ?HungrySingleton?getInstance() {
          ????????
          return ?hungrySingleton;
          ????}

          ????
          ????
          /**
          ?????*?示例業務方法
          ?????
          */

          ????
          public ? void ?demoMethod() {
          ????????
          // do?something
          ????}

          }

          /*
          ?*?懶漢是單例類?Lazy?Singleton
          ?@author?ZhangPu
          ?Feb?22,?2007?7:41:26?PM
          ?
          */


          public ? class ?LazySingleton? {

          ????
          /** ?聲明單例自身實例變量? */
          ????
          private ? static ?LazySingleton?lazySingleton? = ? null ;
          ????
          /**
          ?????*?私有構造
          ?????
          */

          ????
          private ?LazySingleton() {}
          ????
          ????
          /**
          ?????*?單例方法
          ?????*?
          @return
          ?????
          */

          ????
          public ? static ?LazySingleton?getInstance() {
          ????????
          if (lazySingleton? == ? null ) {
          ????????????lazySingleton?
          = ? new ?LazySingleton();
          ????????}

          ????????
          return ?lazySingleton;
          ????}

          ????
          ????
          /**
          ?????*?示例業務方法
          ?????
          */

          ????
          public ? void ?demoMethod() {
          ????????
          // do?something
          ????}

          }


          2、登記式單例類
          主要是解決餓漢和懶漢式單例類不能使用繼承的情況設計的。由父類提供一個集合裝載子類的實例,并通過傳入參數來提供子類的唯一實例。父類實現實例創造和管理,子類傳入參數取得實例。
          package?pattern.singleton;

          import?java.util.HashMap;
          import?java.util.Map;

          /*
          ?@author?ZhangPu
          ?Feb?22,?2007?7:50:28?PM
          ?
          */


          public?abstract?class?RegSingleton?{

          ????
          private?static?Map?registers?=?new?HashMap();
          ????
          ????
          /**
          ?????*?保護默認構造
          ?????*
          ?????
          */

          ????
          protected?RegSingleton(){}
          ????
          ????
          public?static?RegSingleton?getInstance(String?key){
          ????????
          if(key?==?null){
          ????????????key?
          =?"pattern.singleton.RegSingleton";
          ????????}

          ????????
          if(registers.get(key)?==?null){
          ????????????
          try?{
          ????????????????registers.put(key,?Class.forName(key).newInstance());
          ????????????}
          ?catch?(Exception?e)?{
          ????????????????e.printStackTrace();
          ????????????}

          ????????}

          ????????
          return?(RegSingleton)registers.get(key);
          ????}

          ????
          ????
          /**
          ?????*?示例業務方法,子類實現
          ?????*
          ?????
          */

          ????
          public?void?busiMethod1(){System.out.println("busiMethod1");}
          ????
          public?void?busiMethod2(){}
          ????
          public?void?busiMethod3(){}
          }


          package?pattern.singleton;

          /*
          ?@author?ZhangPu
          ?Feb?22,?2007?8:01:27?PM
          ?
          */


          public?class?RegSingletonChild?extends?RegSingleton?{

          ????
          public?RegSingletonChild()?{
          ????????
          //?TODO?Auto-generated?constructor?stub
          ????}

          ????
          ????
          /*
          ?????*?@Override
          ?????
          */

          ????
          public?static?RegSingletonChild?getInstance(){
          ????????
          return?(RegSingletonChild)RegSingleton.getInstance("pattern.singleton.RegSingletonChild");
          ????}


          ????
          public?static?void?main(String[]?args)?{
          ????????RegSingletonChild?reg?
          =??RegSingletonChild.getInstance();
          ????????reg.busiMethod1();
          ????}

          ????
          }

          一個實際的例子
          本例用戶在一個真實的行業管理系統中提供代碼表的鍵值緩存。

          package?net.zphome.tools;

          import?java.util.HashMap;
          import?java.util.Iterator;
          import?java.util.Map;
          import?java.util.TreeMap;

          import?net.zphome.db.DbResultSet;
          import?net.zphome.db.Dbsql;


          /*
          ?@author?ZhangPu
          ?Jul?31,?2006?9:18:25?PM
          ?
          */


          public?class?CacheDD?{

          ????
          ????
          public?static?Map?dd?=?null;
          ????
          ????
          static{
          ????????
          if(dd?==?null){
          ????????????loadDataDictionary();?
          ????????}
          ????
          ????}

          ????
          ????
          public?static?Map?getDDByType(String?typeid){

          ????????
          return?(Map)dd.get(typeid);
          ????}

          ????
          ????
          ????
          public?static?String?getDDWithOption(String?TypeId){
          ????????StringBuffer?sb?
          =?new?StringBuffer();
          ????????
          ????????Map?one?
          =?(Map)dd.get(TypeId);
          ????????Iterator?it?
          =?one.keySet().iterator();
          ????????
          while(it.hasNext()){
          ????????????String?key?
          =?(String)it.next();
          ????????????sb.append(
          "<option?value=\""+key+"\">"+one.get(key)+"</option>\n");
          ????????}

          ????????
          return?sb.toString();
          ????}

          ????
          ????
          public?static?String?getDDWithOption(String?TypeId,String?defaultKey){
          ????????StringBuffer?sb?
          =?new?StringBuffer();
          ????????
          ????????Map?one?
          =?(Map)dd.get(TypeId);
          ????????Iterator?it?
          =?one.keySet().iterator();
          ????????
          while(it.hasNext()){
          ????????????String?key?
          =?(String)it.next();
          ????????????sb.append(
          "<option?value=\""+key+"\"?"+(defaultKey?!=?null?&&?defaultKey.equals(key)?"selected":"")+">"+one.get(key)+"</option>\n");
          ????????}

          ????????
          return?sb.toString();
          ????}

          ????
          ????
          public?static?String?getDDValueByKey(String?TypeId,String?key){
          ????????Map?one?
          =?(Map)dd.get(TypeId);
          ????????
          return?(String)one.get(key);
          ????}

          ????
          ????
          ????
          private?static?void?loadDataDictionary(){
          ????????dd?
          =?new?HashMap();
          ????????
          ????????Dbsql?sql?
          =?null;
          ????????DbResultSet?rs?
          =?null;
          ????????
          try?{
          ????????????sql?
          =?new?Dbsql();
          ????????????String?strSql?
          =?"select?TYPE_ID,DD_ID,DD_NAME?FROM?SYS_DD?ORDER?BY?TYPE_ID?";
          ????????????rs?
          =?sql.executeQuery(strSql);
          ????????????
          if(rs?!=?null){
          ????????????????Map?oneType?
          =?null;
          ????????????????
          int?i?=?0;
          ????????????????String?prevType?
          =?"";
          ????????????????
          while(rs.next()){
          ????????????????????
          if(!prevType.equals(rs.getString(1))){
          ????????????????????????
          if(oneType?!=?null){
          ????????????????????????????dd.put(prevType,oneType);
          ????????????????????????}

          ????????????????????????oneType?
          =?new?TreeMap();?
          ????????????????????}
          ???????????????
          ????????????????????oneType.put(rs.getString(
          2),rs.getString(3));??????????????
          ????????????????????prevType?
          =?rs.getString(1);

          ????????????????}

          ????????????????
          if(oneType?!=?null){
          ????????????????????dd.put(prevType,oneType);
          ????????????????}

          ????????????????rs.close();
          ????????????}

          ????????????
          ????????}
          ?catch?(Exception?e)?{
          ????????????
          throw?new?RuntimeException(e);
          ????????}
          finally{
          ????????????sql?
          =?null;
          ????????}

          ????}

          ????
          ????
          public?static?void?main(String[]?args)?{
          ????????
          /*
          ????????Map?one?=?CacheDataDictionary.getDDByType("1");
          ????????Iterator?it?=?one.keySet().iterator();
          ????????while(it.hasNext()){
          ????????????System.out.println(it.next());
          ????????}
          ????????
          */

          ????????System.out.println(CacheDD.getDDWithOption(
          "1"));
          ????????System.out.println(CacheDD.getDDWithOption(
          "2","1"));
          ????}


          }


          參考:《JAVA與模式》 閻宏 電子工業出版社
          主站蜘蛛池模板: 象州县| 东光县| 连平县| 崇文区| 高台县| 海丰县| 平陆县| 英吉沙县| 仁寿县| 崇文区| 容城县| 连江县| 射洪县| 四川省| 清原| 舟曲县| 交口县| 阿勒泰市| 大安市| 齐齐哈尔市| 广东省| 汝南县| 夏津县| 七台河市| 五大连池市| 昔阳县| 永平县| 东辽县| 南涧| 清远市| 大田县| 曲麻莱县| 靖江市| 图木舒克市| 贵阳市| 万荣县| 江阴市| 秭归县| 德保县| 改则县| 昭觉县|