Fast Lane Reader
拋棄EJB,加速只讀數據的存取。
有些時候,高效地存取數據比獲得最新的數據更重要。在Java Pet Store中,當一個用戶瀏覽商店的目錄時,屏幕與數據庫內容吻合不是至關緊要的,相反,迅速顯示和重新獲得非常重要。FLR模式可以加速從資源中重新獲得大型的列數據項的速度,它不用EJB,而是更直接地通過DAO來存取數據,從而消除EJB的經常開支(例如遠程方法調用、事務管理和數據序列化等)。
在Java Pet Store這個例子中,當一個用戶瀏覽目錄時,通過CatalogDAO(而不是CatalogEJB)從數據庫加載數據項,而CatalogDAO是一個Fast Lane Reader的實例,使得讀訪問變得迅速,如圖4:
圖4 Fast Lane Reader設計模式 (圖片較大 請放大查看)
與DAO模式不同的是,FLR是一個優化的模式,但不是要替代原有的訪問機制,而是作為補充使其完備。當你頻繁地只讀大型的列數據和不必存取最新的數據時,使用FLR將是非常合適的。
Page-by-Page Iterator
為了高效地存取大型的遠程數據列,一下子通過重新獲得其元素為一個子列的Value Object(提高遠程傳輸效率的設計模式,這兒不詳盡描述)。
分布式數據庫的應用經常需要用戶考慮一長列數據項,例如一個目錄或一個搜索結果的集合。在這些情況下,立刻提供全列的數據經常不必要(用戶并不是對所有的數據項感興趣)或不可能(沒有足夠的空間)。此外,當重新獲得一列數據項時,使用Entity Bean的代價將非常高昂,一個開銷來自于使用遠程探測器來收集Requested Bean,另外,更大的開銷來自對每個Bean產生遠程調用以從用戶獲得數據。
通過Iterator,客戶機對象能一下子重新獲得一個子列或者頁的Value Object,每一頁都剛好滿足客戶機的需求,因此,程序使用較少的資源滿足了客戶機的立刻需求。
在Java Pet Store這個例子中,JSP頁面product.jsp任何時候只顯示一個數據列的一部分,從ProductItemListTag(Page-by-Page Iterator)重新獲得數據項,當客戶機希望看到列中的別的數據項,product.jsp再次調用Iterator重新獲得這些數據項,流程見圖5:
圖5 Page-by-Page Iterator設計模式 (放大查看)
以上設計模式的應用向我們表明,在某些特殊情況下,優化對數據庫的訪問模型,既可滿足用戶的需求又可提高訪問數據庫的效率。這給我們一個思路,就是:在你的硬件環境可能會產生瓶頸的情況下,可以通過對軟件模型的優化來達到滿足需求的目的。上述三種設計模式的應用情形為:
Data Aclearcase/" target="_blank" >ccess Object | 需要將商業邏輯和數據存取邏輯分離; 在調度的時刻,需要支持選擇數據源的類型; 使用的數據源的類型的變化,對商業對象或其它客戶端完成數據存取沒有影響。 |
Fast Lane Reader | 面對大型的列數據,需要經常的只讀訪問; 訪問最新的數據并不是至關緊要的事情。 |
Page-by-Page Iterator | 存取大型的服務器端數據列; 任何時刻,用戶只對列的一部分內容感興趣; 整個列的數據不適合在客戶端顯示; 整個列的數據不適合在存儲器中保存; 傳輸整個列的數據將耗費太多的時間。 |
在顯示商品目錄的時候,我們選擇了DAO和FLR的結合,因為它們兩者的條件都得到了滿足(需要分離商業邏輯和數據存取邏輯,經常的只讀訪問和對即時性不敏感),此時應用將會大大發揮它們的優點。而在進行內容檢索的時候,我們會選擇PPI,因為也許檢索出了上千條的記錄,但是用戶沒有興趣立即閱讀全部內容,而是一次十條地閱讀,或者他在閱讀完前十條記錄后發覺自己的目的已經達到,接下來瀏覽別的網頁了,都不必我們一次性地傳輸上千條記錄給他,所以也是PPI的應用條件得到了滿足,結果則是此模式的優點得到了發揮,又不影響全局的數據訪問。
在進行軟件模型的設計時,整體的框架可以應用某些優秀的、通用的設計模式,這樣既加快模型的建立速度,又能和其它系統集成。但是,碰到一些瓶頸問題的情況下,我們就需要對局部的設計模式做一些調整,以優化整個系統,上述三個模式就是對原有體系的補充,它們并沒有對整體的框架做出巨大的改變,卻突破了某些瓶頸(瓶頸往往是局部的)障礙,讓我們的產品更好地服務于用戶。
將深入研究的問題
開篇至今,我們主要探討了軟件層次上的解決問題,但是,必須肯定一點,如果你的硬件環境非常差(運行Java都有困難)或非常好(額外的存儲空間、超快的運算速度和富裕的網絡帶寬),上述途徑對你來說很難有大的幫助。前一種情況,我建議你升級硬件設備到軟件廠商推薦的配置(強烈反對最小配置),以使應用服務器、數據庫、Java等軟件能夠運行自如;后一種情況,我沒什么話可說,花錢是解決這個問題最好的辦法。
本文并未談及線程池和告訴緩沖這兩個非常重要的概念,因為筆者認為,它們是針對局部時間高訪問量的瓶頸問題的解決,不能理解為簡單的速度瓶頸問題,所以我會在下一篇文章中分析這種特殊的情況和提出解決問題的辦法。也許你對這一點更關心一些,認為自己的問題就出在這個地方,這是非常好的思考問題的方式,你已經抓住了問題的關鍵。但是,我還是建議你通讀一下本文,讓自己對速度瓶頸問題有更好的理解,并掌握在解決問題的過程中,分辨常態和暫態,從而選擇不同的思路入手。其實,本文談及的就是速度瓶頸問題的常態,而下一篇文章討論的將會是暫態,希望你能夠漸入佳境。
JDO(Java Data Object)是需要我們關注的一個API,它定義了新的數據存取模型,直接借鑒了DAO設計模式。不同的數據源,有不同的數據存取技術,就有不同的API供開發人員使用。JDO正是為了解決這個問題而產生的,它實現了即插即用的數據存取的實現和持久信息(包括企業數據和本地存儲的數據)以Java為中心的視圖。因此,開發人員只關注創建那些實現商業邏輯的類和用它們來表現數據源的數據,而這些類和數據源之間的映射則由那些EIS領域的專家來完成。如果大家對JDO感興趣的話,那么我會寫第三篇文章把其詳細介紹給大家,并給出示例應用。
原文轉自:http://www.anti-gravitydesign.com