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

              Factory模式在這里起到連接接口和實現的橋梁作用,通過Factory模式,我們可以根據具體需要加載相應的實現,并將此實現作為所對應接口的一個實例提供給業務層使用:
             
              為了提高性能,避免每次調用都讀取配置文件所引起的大量磁盤操作,采用了HashMap作為DAO緩存實現示例:
            
          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();//根據配置文件加載DAO實現配置
                  }
                }
              }
              
          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索引,實現類作為值
                      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;
                }
              }
              業務層通過接口調用底層實現,具體的DAO實現類不會出現在我們的業務代碼中。而具體實現類在配置文件中加以配置,之后DAOFactory.getDAO方法通過讀取配置文件獲得當前我們期望使用的實現類的類名,在通過Java Class動態加載機制加載后返回。

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

          posted @ 2009-10-06 09:23 王永慶 閱讀(162) | 評論 (0)編輯 收藏
              現在有越來越多的關鍵應用和大型應用是基于J2EE 來創建的,像銀行系統和帳單系統這些關鍵應用要求有很高的可用性,而Google Yahoo 這樣的大型應用就需要很好的可擴展性。在如今這個聯系越來越緊密的世界,高可用性和良好的可擴展性的重要性日益突出。例如在1999 6 月份,eBay 的服務停止了22 個小時,導致大約230 萬的拍賣被中斷,eBay 的股票也隨之下降
          9.2 個百分點。
                 J2EE
          集群就是一種能夠提供高可用性、可擴展性以及容錯性的流行技術。但是由于在J2EE 規范中沒有對集群做出規范,各個J2EE 廠商就使用不同的方式來實現集群,這樣就給系統架構師和開發人員帶來了很多麻煩。下面就是常見的一些問題:
          •    
          為什么帶有集群支持的商業J2EE 服務器產品如此昂貴?(是無集群支持產品的10 倍)
          •    
          為什么在單機環境下創建的應用在集群環境中無法正常運行?
          •    
          為什么我的應用在集群環境下運行的非常慢,但是在單機模式下卻沒有這個問題?
          •    
          為什么我的集群應用在向其他廠商的服務器遷移時會失敗?
          要理解為什么會有這些限制,最好的方法就是研究它的實現,以揭開J2EE 集群的面紗。

           
          基本術語
                
          在我們開始討論對于集群不同的實現之前,我想,了解一下集群技術的一些基本概念還是很有意義的。希望本章不單單是告訴你這些概念和設計問題,也同時能夠為你勾勒一下不同J2EE集群實現的框架以便于理解。
          可擴展性
                
          在一些大型系統中,很難提前預知最終用戶的數量以及他們的使用行為,所以,可擴展性就是指一個系統能夠快速適應用戶數量的增加。提高服務器處理能力的最直 接的方法就是增加硬件資源,例如CPU、內存或者硬盤等。集群是解決這個問題的另外一種方式,它使得一組服務器共同分擔繁重的任務,但對于最終用戶來說就 像一臺服務器。

          高可用性
              
          通過向單機添加硬件來擴展系統能力的方案并不可靠,因為單一的服務器存在一個單點故障。像銀行系統、帳單系統這樣的關鍵應用甚至連一分鐘的停機都不能容 許,它們需要在任何時間都是可用的,并且要能夠保證響應速度。集群技術就可以滿足這個要求,它通過加入冗余服務器使得在一個服務器出錯而停止服務的時候, 這些冗余的服務器可以繼續服務。

          負載均衡
              
          負載均衡是集群的另外一個關鍵技術,它通過將請求分發到不同的服務器來達到高可用性和高效的處理能力。負載均衡器可以是一個servlet,也可以是一個 插件(例如Linux 上的ipchains),甚至還可以是一個比較昂貴的內嵌了SSL 支持的硬件產品。為了能夠分發請求,負載均衡器還需要做一些重要的工作,例如使用會話粘滯技術以確保來自同一個用戶的請求會被轉發到同一個服務器;使 健康檢查(或者心跳監聽)技術來防止將請求轉發到一個失敗的服務器;有時候負載均衡器還將參與失敗轉移的工作。

          容錯
                
          高可用的數據并不必是嚴格正確的數據。在J2EE 集群中,當一個服務器實例失敗了,在集群中冗余的服務器就可以處理新到的請求,這樣就保證了服務依然可用。但是在服務器失敗的那一刻,正在被處理的請求就 可能無法得到正確的數據。那么,帶有容錯功能的集群就可以確保請求所得到的數據是正確的,哪怕是服務器端出現了錯誤。
                
          這個是怎么實現的呢?確實需要我們去進行思考!

          失敗轉移
                
          在集群中,失敗轉移是實現容錯的一個關鍵技術。當最初的節點失敗之后,在集群中選擇另外一個節點來完成處理。失敗轉移到其他節點可以通過編碼實現,也可以由平臺自動實現。

          冪等方法
                
          如果一個方法使用同樣的參數進行多次調用所得到的結果都一樣,也就是說對于該方法的調用次數不影響系統,那么這個方法就叫做冪等方法。例如 “getUsername()”就是一個冪等方法,而“deleteFile()”就不是冪等的。在討論 HTTP 會話失敗轉移和EJB 的失敗轉移時,冪等方法是一個很重要的概念
          posted @ 2009-10-05 11:59 王永慶 閱讀(236) | 評論 (0)編輯 收藏

          /輕量:其實是使用難易程度,從根本上說,重/輕量應該和可伸縮性不矛盾的,特別是EJB 3.0推出以后,這個問題應該得到比較好的解決。
             但是,在目前情況下,編寫一個JavaBeans要比編寫一個EJB容易多,那么,是重/輕量還是可伸縮性應該成為系統架構的主要依據呢? 在這個問題背后,還隱藏了目前在開源領域兩個架構技術選擇:
            1. 重量:基于JBoss/EJB的完整J2EE系統架構 (具有可伸縮性,目前不易于學習)
            2. 輕量:基于TomcatStruts+Hibernate/Spring+Hibernate (目前無太大可伸縮性,但是易于學習使用)

          因為輕量解決方案易于學習新技術,容易使用,選中率比較高。但是讓人產生對系統的可伸縮性擔憂。鑒于這種情況,我認為有必要強調一下可伸縮性的重要性,切不能因為要跟進新的設計思想和技術,而盲目地采用一個無可伸縮性的設計方案。

          其實,"輕量"應該是一個中性詞,但是因為大量新的設計思想比較容易通過輕量方案獲得成型軟件,如(Spring/Naning/Hibernate)等,逐漸的"輕量"好像變成了一個褒義詞。 如果從可伸縮性的標準看,輕量還可能是一個貶義詞,輕量意味著喪失重量系統中的分布式網絡計算的設計考量,那么可伸縮性就要打問號。

          從這次JavaOne大會以及從長遠來看,隨著EJB 3.0中間件輕量化、SOA架構理念普及,輕量/重量的區別已經模糊,如果還是以輕量/重量作為架構選擇的標準,甚至標榜自己的系統,無疑是不明智的。

          可伸縮性應該依然是實用企業系統架構的主選,可伸縮性是站在軟件公司的客戶企業立場,為這些客戶企業考慮的,但是他們經常因為被認為是外行,擋在了軟件系統架構選擇的門外。
          posted @ 2009-10-05 11:55 王永慶 閱讀(154) | 評論 (0)編輯 收藏

          可伸縮性:所謂可伸縮性,是指在小型規模單臺服務器情況下,應用系統可以良好運轉,系統的訪問量或功能增加后,整個系統只需通過增加服務器硬件就可以實現性能擴展,無需修改太多軟件。對于可伸縮性平臺(如JBoss)來說,理論上,沒有最大負載或最多在線人數這樣的概念。

          posted @ 2009-10-05 11:54 王永慶 閱讀(285) | 評論 (0)編輯 收藏
              持久:英文即Persistence,簡單來講,也就是把數據保存到可掉電式存儲設備中供之后使用。數據持久化往往意味著將內存中的數據保存到磁盤上加以固化,而持久化的實現過程則大多通過各種關系型數據庫來完成。
              持久層:也就是在系統邏輯層面上,專注于實現數據持久化的一個相對獨立的領域。
              所謂的持久層,其判定標準
              1、如果表示層發生變化,需要從JSP遷移到Java WebStart Client,我們的數據庫代碼是否需要重新編譯。
              2、如果業務邏輯層發生了變化,那么數據持久化代碼是否需要重新編譯?
              3、如果地秤數據庫持久化機制發生了改變,那么,系統中的非持久化部分代碼是否需要重新編譯?
             
              何謂耦合:就是事務之間的相互關聯關系
              何謂解耦:即采用一些手段降低關聯的緊密程度。
              我們需要的是一個粒度適中的耦合關系,而并非完全意義上的松耦合。
             
              軟件系統的研發過程中,貫穿了技術層面和業務層面的代碼實現過程。程序邏輯必須結合業務領域內相應的數據和系統資源,反映出特定的業務邏輯。對于一個業務系統而言,系統研發的目的是為特定業務提供支持,業務邏輯往往是系統實現的核心。此時,將業務邏輯與數據訪問邏輯相分離尤為重要。

              在業務邏輯的實現過程中,我們應該避免業務邏輯代碼中混雜數據訪問代碼,而同樣,數據訪問代碼中,也應該避免出現業務邏輯代碼。

              通過良好的設計將邏輯結構與物理結構相分離。這里所謂的物理結構并非傳統意義上的硬件設備,而是我們所無法控制的系統層面,如底層數據庫接口。

              目標只有一個,底層實現變動的情況下,盡量避免對上層結構產生影響。一個設計良好的持久層實現,即便從oracle切換到mysql數據庫,也不會引起大范圍的代碼變更。

              DAO(Data Access Object)模式,DAO模式實際上是2個模式的組合,即Data Accessor模式和Active Domain Object模式,其中Data Accessor模式實現了數據訪問和業務邏輯的分離,而Active Domain Object模式實現了業務數據的對象化封裝,一般我們將這2個模式組合使用。
              DAO模式通過對業務層提供數據抽象層接口,實現了以下目標:
              1、數據存儲邏輯的分離
              通過對數據訪問邏輯進行抽象,為上層結構提供抽象化的數據訪問接口。業務層無需關心具體的select,insert,update操作,這樣,一方面避免了業務代碼中混雜JDBC調用語句,使得業務邏輯實現更加清晰,另一方面,由于數據訪問接口與數據訪問實現相分離,也使得開發人員的專業劃分成為可能。
              2、數據訪問底層實現的分離
              DAO模式通過將數據訪問劃分為抽象層和實現層,從而分離了數據使用和數據訪問的底層實現細節。這意味著業務層與數據訪問的底層細節無關,也就是說,我們可以在保持上層結構不變的情況下,通過切換底層實現來修改數據訪問的具體機制。
              3、資源管理和調度的分離
              在數據庫操作中,資源的管理和調度是一個非常值得關注的主題。大多數系統的性能瓶頸往往并非集中在業務邏輯處理本身。DAO模式將數據訪問邏輯從業務邏輯中脫離出來,使得在數據訪問層實現統一的資源調度成為可能,通過數據庫連接池以及各種緩存機制的配合使用,往往可以在保持上層系統不變的情況下,大幅度提升系統性能。
              4、數據抽象
              DAO模式通過對底層數據的封裝,為業務層提供一個面向對象的接口,使得業務邏輯開發人員可以面向業務中的實體進行編碼。通過引入DAO模式,業務邏輯更加清晰,且富裕形象性和描述性。

          posted @ 2009-10-05 10:32 王永慶 閱讀(247) | 評論 (0)編輯 收藏
              終于又開始寫博客了,當初不知什么原因把自己從前寫的技術文章(雖然都是書本上的知識)全都刪除了,前端時間的工作差點使自己崩潰。10.1前和從前的朋友去吃了頓飯,這頓飯使我受益匪淺,最近一直在思考換工作,他說即時換了工作也就是錢多一點,你自己根本就不知道要什么,確實,這幾年工作我真的不知道要什么(也許有的人和我有一樣的感覺,做我們這行的),換工作的頻率不算高,也不算低,每一年換一次,不知道自己的下一個目標在哪里,為了錢而換工作么,還是為了一個好的工作環境,工作只是暫時的,最主要的是自己知道想要什么,我現在也不知道自己想要什么,但是目前的目標是確定了,找個好點的工作,慢慢想吧。
              已經有一個多月沒看書了,早上9點上班,晚上10點下班,下班之后,洗把臉就睡覺,不知道自己怎么這么累,說不上來,可能是胡思亂想。經過10.1的休息,感覺自己有了點明確的目標,最起碼知道自己要干什么,雖然不知道自己想要什么,
          先寫到這里。

          posted @ 2009-10-05 09:47 王永慶 閱讀(122) | 評論 (0)編輯 收藏
          僅列出標題
          共7頁: 上一頁 1 2 3 4 5 6 7 
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          關注blogs

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 宽甸| 灵台县| 慈溪市| 板桥市| 彰武县| 商洛市| 奎屯市| 梓潼县| 德化县| 瑞金市| 庆安县| 甘泉县| 綦江县| 嘉祥县| 满洲里市| 阜南县| 沾益县| 十堰市| 库伦旗| 陆河县| 衡水市| 汕尾市| 读书| 无为县| 新郑市| 思南县| 离岛区| 西藏| 固阳县| 安国市| 山西省| 磐安县| 方城县| 遂川县| 余干县| 任丘市| 湟中县| 百色市| 鄂伦春自治旗| 东明县| 本溪市|