posts - 66,  comments - 11,  trackbacks - 0
              DAO模式實際是2個模式的組合,即Data Accessor和Domain Object模式
              Data Accessor即將數(shù)據(jù)訪問的實現(xiàn)機制加以封裝,與數(shù)據(jù)的使用代碼相分離,從外部來看,Data Accessor提供了黒盒式的數(shù)據(jù)存取接口。Domain Object則提供了對所有面向領(lǐng)域內(nèi)對象的封裝。
             
              DAO模式實現(xiàn)了業(yè)務(wù)邏輯與數(shù)據(jù)邏輯的分離。對于專項開發(fā)而言,這樣的分離設(shè)計差不多已經(jīng)可以實現(xiàn)開發(fā)過程中業(yè)務(wù)層面和數(shù)據(jù)層面的相對獨立,并且在實現(xiàn)復(fù)雜性與結(jié)構(gòu)清晰性上達(dá)到較好的平衡。
              對于一個產(chǎn)品化的業(yè)務(wù)系統(tǒng)而言,軟件產(chǎn)品往往需要在不同客戶環(huán)境下即時部署。由于java良好的跨平臺支持,我們在操作系統(tǒng)之間大可以輕易遷移,但在另外一個層面,數(shù)據(jù)庫層,卻仍然面臨著平臺遷移的窘境。針對不同的數(shù)據(jù)庫,我們可以實現(xiàn)針對不同類型數(shù)據(jù)庫的Data Accessor,并根據(jù)客戶實際部署環(huán)境,通過類文件的靜態(tài)替換來實現(xiàn)。這樣將大大增加部署和維護(hù)工作的難度和復(fù)雜性。我們應(yīng)該將此類因素帶來的變動屏蔽在系統(tǒng)之外。

              Factory模式在這里起到連接接口和實現(xiàn)的橋梁作用,通過Factory模式,我們可以根據(jù)具體需要加載相應(yīng)的實現(xiàn),并將此實現(xiàn)作為所對應(yīng)接口的一個實例提供給業(yè)務(wù)層使用:
             
              為了提高性能,避免每次調(diào)用都讀取配置文件所引起的大量磁盤操作,采用了HashMap作為DAO緩存實現(xiàn)示例:
            
          public class DAOFactory{
                
          private static HashMap daoMap = null;
                
          public static Object getDAO(Class daoInterface){
                  initial();
                  Object dao 
          = daoMap.get(daoInterface);
                  
          if(null == dao){
                    
          throw new DAOException();
                  }
                  
          return dao;
                }
                
          public static synchronized void initial(){
                  
          if(null==daoMap){
                    daoMap 
          = DAOConfig.load();//根據(jù)配置文件加載DAO實現(xiàn)配置
                  }
                }
              }
              
          public class DAOConfig{
                
          private static Logger logger = LogManager.getLogger(DAOConfig.class);
                
          private static final String DAO_CONFIG_FILE = "dao.xml";
                
          private static final String DAO_CONFIG_SECTION = "DAO";
                
          public static synchronized HashMap load(){
                  HashMap map 
          = new HashMap();
                 
                  JFigLocator jfigLocator 
          = new JFigLocator(DAO_CONFIG_FILE);
                  Properties  prop 
          = daoConfig.getSectionAsProperties(DAO_CONFIG_SECTION);
                  Enumeration enumSection 
          = prop.keys();
                  
          while(enumSection.hasMoreElements()){
                    String daoIface 
          = (String)enumSection.nextElement();
                    String daoImpl 
          = prop.getProperty(daoIface);
                    
          try{
                      Class iface 
          = ClassToolkit.loadClass(daoIface);
                      Class impl 
          = ClassToolkit.loadClass(daoImpl);
                      
          //將接口作為HashMap索引,實現(xiàn)類作為值
                      map.put(iface,impl);
                    }
          catch(ClassNotFoundException e){
                      logger.debug(
          "No Class Found=>"+e);
                    }
                  }
                  
          return map;
                }
              }
            
          <?xml version="1.0" encoding="UTF-8"?>
              
          <configuration>
                
          <section name="DAO">
                  
          <entry key="net.xiaxin.lab.persistence.dao.iface.CustomerDAO" value="net.xiaxin.lab.persistence.dao.impl.CustomerDAOImp_Mysql"/>
                  
          <entry key="net.xiaxin.lab.persistence.dao.iface.PromotionDAO" value="net.xiaxin.lab.persistence.dao.impl.PromotionDAOImp_Mysql"
                </section
          >
              
          </configuration>

            
          public class ClassToolkit{
                
          public static Class loadClass(String className){
                  Class cls 
          = null;
                  
          try{
                      cls 
          = Thread.currentThread().getContextClassLoader().loadClass(className);
                  }
          catch(Exception e){
                    e.printStackTrace();
                  }
                  
          if(cls == null){
                    cls 
          = Class.forName(className);
                  }
                  
          return cls;
                }
              }
              業(yè)務(wù)層通過接口調(diào)用底層實現(xiàn),具體的DAO實現(xiàn)類不會出現(xiàn)在我們的業(yè)務(wù)代碼中。而具體實現(xiàn)類在配置文件中加以配置,之后DAOFactory.getDAO方法通過讀取配置文件獲得當(dāng)前我們期望使用的實現(xiàn)類的類名,在通過Java Class動態(tài)加載機制加載后返回。

              通過接口與實現(xiàn)的分離,并結(jié)合DAOFactory動態(tài)加載實現(xiàn)類,我們實現(xiàn)了底層訪問實現(xiàn)的參數(shù)化配置功能。
              無論有多好的理由,新的設(shè)計必須避免影響業(yè)務(wù)邏輯代碼的可讀性。沒有哪個物業(yè)公司能說服你在自己的房屋中增加一條穿堂而過的管道,而理由是為了實施更好的供暖設(shè)計,我們的軟件也一樣。

          posted on 2009-10-06 09:23 王永慶 閱讀(164) 評論(0)  編輯  收藏 所屬分類: HIBERNATE
          <2009年10月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          關(guān)注blogs

          搜索

          •  

          最新評論

          • 1.?re: 心中的那個她[未登錄]
          • 如果心情能那么容易放開就好了,碰到她是我的緣分,但是她的緣分不知道在哪里。
          • --王永慶
          • 2.?re: 心中的那個她[未登錄]
          • 兄弟,喜歡就大膽去追好了,就是因為喜歡才會有不愉快,如果想一輩子沒有這些煩惱,找一個可有可無的人就好了。這種事講的是緣分吧。別人對你好不好其實不太重要。放開心情就好了。
          • --萍水相逢
          • 3.?re: 心中的那個她
          • 只能同甘不能共苦,就他媽算了吧,程序員也是人??!我現(xiàn)在也很討厭女的不理解人情。
          • --咖啡妝
          • 4.?re: 難以割舍的那份情感
          • 評論內(nèi)容較長,點擊標(biāo)題查看
          • --王永慶
          • 5.?re: 難以割舍的那份情感
          • 評論內(nèi)容較長,點擊標(biāo)題查看
          • --隔葉黃鶯

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 洛川县| 班戈县| 双峰县| 怀来县| 泌阳县| 武清区| 磐石市| 荆门市| 安阳县| 潼关县| 财经| 格尔木市| 通州区| 青铜峡市| 甘泉县| 托里县| 电白县| 绥化市| 堆龙德庆县| 巴彦县| 马公市| 西林县| 永定县| 香港 | 获嘉县| 乌苏市| 江门市| 高雄县| 富顺县| 原平市| 莱阳市| 临泽县| 如东县| 罗山县| 工布江达县| 洪洞县| 建阳市| 莱西市| 长汀县| 开封县| 政和县|