<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Dict.CN 在線詞典, 英語學習, 在線翻譯

    都市淘沙者

    荔枝FM Everyone can be host

    統計

    留言簿(23)

    積分與排名

    優秀學習網站

    友情連接

    閱讀排行榜

    評論排行榜

    Tapestry Spring Hibernate (zhuan)

     

    Web層的Tapestry負責數據輸入輸出, 響應用戶事件,及輸入校驗的工作, 通過訪問預先加載的WebApplicationContext(由Spring提供, 包含著所有Service bean)獲得Service層的Service Bean, 把業務操作都委托給它們.

    Service層的bean則負責use case邏輯, domain相關的邏輯委托給domain model中的bean去實現. Service通過DAO完成對domain model的持久化工作. Service負責數據庫事務和Hibernate Session的管理(通過Spring的聲明式事務管理和與之集成的Hibernate Session管理). Service層的另一項重要工作是權限和訪問控制。

    Domain model負責表示問題域的數據和domain logic. DAO使用Hibernate持久化數據以及查詢. 在實現DAO時, 我們使用了Spring的Hibernate DAO Support,極大地簡化了代碼, 很多方法都只用簡單的一行完成. 有意思的是, 最后完成的HibernateDAO的代碼量居然比我寫的MockDAO的代碼少了一半還多

    這樣的架構優點很明顯, 層次清晰, 各層的職責也明確, 便于分層設計與開發, 結合mock和spring的IOC, unit test也是非常容易的. 而且后臺(Service, domain model and DAO)的代碼不依賴于Web容器或是EJB容器的API, 移植性非常好, 同樣的代碼可以在Web app中使用也可在普通的Java app中使用, 只需更換UI層.

    按照這個整合的構架,我們實現一個簡單的實例,實現了列表分頁查詢和顯示,數據增刪改,基于Hibernate Criteria Query提供了一個比較通用的查詢機制。利用Middlegen和Velocity我們可以從已經建好的數據庫表結構自動生成Hibernate映射文件,實體類和DAO,極大地減少了工作量。我們還對這個小例子進行了壓力測試(測試時的數據量為10萬條記錄),確定平臺不存在性能問題。

    通過這個實例我們把整個架構基本走通一遍,并總結了使用這套架構開發時適用的開發流程和需要做的工作。

    困擾的問題

    問題1:要不要使用DTO?
    在上面的架構中我們并沒有明確Service和Web層間的數據傳輸是如何進行的。我們討論好久要不要使用DTO,最后的結論是不用。

    使用DTO有兩個主要的理由:
    1、減少Web層和Service層間的方法調用,通過一個方法調用就將Web需要的數據都傳給Web。
    2、隔離domain model和Web層。

    第一個理由在當前架構下是不成立的。因為我們的架構是集中式的,Web和Service是在同一個JVM中,它們之間的方法調用是沒有EJB遠程訪問的巨大消耗的。
    第二個理由還是需要考慮的。如果允許把domain model中的對象傳給Web層,那么修改domain model,就會影響到Web層。
    如果使用DTO,那么domain model實現上的變化就不會影響到Web。但是大量的變化不是domain model實現上的變化,而是domain model接口的變化,比如一個domain model的對象上添加了一個屬性,而這個屬性需要用戶修改,那么這時候必須修改Web層,不管是不是用了DTO。
    而且使用DTO,就需要維護著一大堆對象,或是它們的生成器,這是非常無聊、且容易出錯的工作。
    基于這些考慮,沒有必要使用DTO, 直接把domain object傳給Tapestry的web層,利用Tapestry提供強大的數據綁定和組件功能很方便

     

    問題2:Entity like domain model or rich domain model?
    我們使用Middlegen自動生成Hibernate映射文件,Entity類和DAO類, 但是生成的Entity只含有簡單的屬性和getter, setter方法。
    因此我們遇到了一個問題:我們的domain model還要不要包含domain logic?如果包含,那么和自動生成工具如何結合?
    雖然一個rich domain model可以減少Service中的重復代碼,提高復用性。 但是如何同自動生成結合?
    或許可以使用<meta>標簽,生成抽象基類,我們繼承這些自動生成的基類,添加業務方法。
    但是單純從結構的分離角度來考慮, domain model不應該包括復雜的domain logic, 只是作為一個data model bean, 再加上一些簡單的logic, 比如addChild的同時,設置child的parent此類簡單logic
    而且在POJO里面塞太多業務邏輯會導致Hibernate產生你預想不到的后果。

     


    問題3:Model driven or Data driven?
    這其實是一個很無聊的問題. 采用Model driven還是Data driven的方式一直都處于熱烈的討論中。我們主要是受到Rod Johnson(Expert one-on-one J2EE Design and Development 一書的作者) 的影響,采用了Data driven的方式。先作數據庫設計,生成庫表,然后用Middlegen反向生成Hibernate映射文件和Entity及DAO。
    但是在進入項目應用之后發現這種方法有可能會出現兩個問題:
    a) 數據庫設計僅說明了系統要管理的靜態數據,我們還是得作面向對象分析,以反映系統的動態行為。特別是當系統的業務不僅僅是簡單的CRUD操作時,這個問題更嚴重。
    b) 數據庫設計為了優化性能,可能會把好幾個應該是單獨實體的數據放入一個實體中。這樣如果直接把這種極粗粒度實體映射成Entity類,那簡直是不可接受的。
    面向對象的分析設計模型得到的類都是相當細粒度的。這種情況還得作面向對象的分析,明確到底這個粗粒度的大表應該映射成那幾個細粒度的對象。
    如果采用Model driven,則可以用AndroMDA生成domain model,Hibernate DAO,Hibernate mapping,數據庫表,簡單的Service和前臺的Tapestry頁面。
    不過換個角度分析, 采用哪種設計模式只是個人習慣而已,無論是Model driven或者Data driven,對于相同的需求,2者最終的設計應該都是很類似的。
    更周全的做法大概可以從2邊同時考慮的,一邊做Model,一邊還要考慮數據庫的結構, 再進行相應的調整,用下來也沒有什么問題。沒有用代碼生成,
    只是用Hibernate的Eclipse plugin (Hibernate Synchronizer)來幫我做一些code assist. 也可以用xDoclet來生成mapping文件和DDL.

     

    問題4:Hibernate Session生命周期如何管理?
    對于Hibernate Session的生命周期我們采用的是Session-per-Transaction模式,未采用Open Session in View模式。
    雖然Hibernate team認為這種方法沒什么不好,而且FreeRoller和Atlassian的confluence都使用了Open Session In View這種模式,但是我們對它可能產生的影響還沒有很好的把握,所以暫時棄置不用。
    如果Web層要訪問lazy load的數據, 需要先調用Service的業務方法, 以獲得數據. 不過Open Session in View模式其實并不復雜.


    問題5:Use case logic 和 domain logic 如何區分?
    Service負責use case logic,domain model負責domain logic。這樣的劃分看起來很好,實現起來就很麻煩。
    如何確定什么是use case logic,什么是domain logic?
    不過如果像第二個問題中最后所說, domain model里面沒有什么domain logic 的話,這個問題不存在


    問題6:Service粒度如何確定?
    這個問題真是很煩,原先考慮使用usecase controller的方式,每個usecase對應一個Service,但是發現這樣復用性太低,而且好多地方必須復用相同的功能
    另一種方法是用package level service,每個package作個service,這樣倒是可以重用,但是感覺太死了,不好。
    回到domain model里面沒有什么domain logic的情況下,Service的功能就切得很細,盡量重用,一個package可能有多個service

    現在也沒有什么很好的辦法,只好在詳細設計時根據具體情況確定需要多少個Service了。TBD.

    問題7:權限如何設定?如何檢查?
    權限設定也是個頭疼的問題。我們本想是按照use case設定權限,每個用例一個權限。在角色設定的時候直接處理的都是業務意義非常明確的權限。
    但是在權限驗證過程中發現了問題:如果在Service的方法中驗證權限,而且這個方法在多個用例中用到(復用Service),那么這個Service的方法就需要檢查多個權限; 如果每個Service方法對應一個權限, 那么權限又太細了, 不像use case權限那樣代表一個完整的業務.
    一種考慮是將權限控制都做在Service上,權限系統的設計理念來自于Unix操作系統的權限策略,只不過我把文件和文件夾換成了Service,把組換成了Role,此外又加了一些控制對象進去,這樣實現下來功能相當的強大,而且很靈活,擴展起來很方便,增加一個Service,只需要在配置文件里面設定該Service的權限級別就行了.
    時針對Service的權限是得自己寫代碼實現的,先是定義一個權限控制接口,然后寫了一個抽象類繼承該權限接口,把主要的代碼實現都寫好了,針對特定的Service不同的部分定義為一個抽象方法,其實該抽象方法也就是把類名傳遞過去而已。這樣每個要實施權限控制的Service只要繼承該抽象方法,然后在配置文件里面定義自己的權限級別就行了。就算以后再增加別的Service模塊,也非常快捷,不需要動現有的代碼
    如果結合了Spring, 在Spring里面可以使用AOP的辦法針對Service增加權限控制,而不需要自己手工寫.
    看起來手工方式還是沒有上面描述的Spring控制方式優雅

     

    額外的問題:
    從問題5/6中再上升一步, 考慮一下DAO的做法.一種常見的用法是寫一個通用的DAO類, 而是整個系統就一個DAO (PersistenceManager), 里面只有create, update, delete entity這3個方法。另外寫一個DAO, 專門做查詢 (QueryManager), 用hibernate的named query做常用的查詢, 用criteria來做基于用戶輸入的動態查詢.
    criteria 和 named query其實都是hardcode,domain object attribute name改變的時候,還得記得手工去修改這些代碼,unit test很難覆蓋到所有的criteria search 和 named query里面的代碼.
    DAO是為了切換持久層API用的,準確的來說,是當你在使用JDBC來直接訪問數據庫的時候,由于不同的數據庫的sql有差別,所以需要一個DAO來切換不同的數據庫的JDBC訪問代碼。每個數據庫的JDBC代碼你都要寫一套,當切換數據庫的時候,就可以通過DAO來切換不同的JDBC代碼實現了.
    是當我們使用Hibernate的時候,除了個別情況,大部分時候是不需要考慮跨數據庫問題的,Hibernate已經做的足夠好了。個別情況下的代碼我們也可以單獨做為特例處理,因此我想不到DAO的必要性了。
    如果說使用DAO是為了將來切換別的O/R Mapping的話,我覺得這個話是不現實的,畢竟每種O/R Mapping的實現方式差異還是很大的,這直接影響到整個持久層設計.
    而當業務層代碼是直接調用Hibernate API來操縱PO的,持久層就只剩下了簡單的POJO了.
    另外一種常見用法是而在業務層針對每個POJO,寫一個對他的CRUD操作的Manager類. 可以參看一下Appfuse的做法.其實這等于是在完成DAOImpl應該完成的工作,只不過現在把他歸到了業務層來說罷了。然后你就可以根據你的業務邏輯來寫你的業務Service了
    在這里,至于如何切換業務邏輯的顆粒度問題, 基于OOAD的原則,應該把無關的業務放在不同的class里面,降低類之間的耦合性,提高類的可重用度。那么根據這個原則如何切分就是一個清楚的事情了.


    (以上文字整理自洛賓,QW等N人在爪哇愛死論壇上的討論)

    posted on 2006-02-26 10:33 都市淘沙者 閱讀(498) 評論(0)  編輯  收藏 所屬分類: Spring+Struts+Hibernate

    主站蜘蛛池模板: 亚洲AV日韩AV无码污污网站| 亚洲色图校园春色| 国产午夜亚洲精品不卡电影| 久久久久久99av无码免费网站 | 中文字幕免费在线播放| 亚洲成AV人在线观看网址| 在线观看亚洲免费视频| 国产大片免费观看中文字幕| 成a人片亚洲日本久久| 国产人成免费视频| sss在线观看免费高清| 亚洲桃色AV无码| 99久久久国产精品免费蜜臀| 亚洲激情电影在线| 国产精品成人免费视频网站京东| 亚洲国产欧美一区二区三区| 免费一看一级毛片人| 中文字幕视频免费在线观看| 97久久精品亚洲中文字幕无码| 精品国产免费人成电影在线观看 | 中文字幕免费视频一| 亚洲a级在线观看| 四虎永久免费观看| 岛国岛国免费V片在线观看| 亚洲AV第一页国产精品| 国产成人免费网站| 免费精品视频在线| 亚洲AV永久无码精品成人| 波多野结衣免费在线观看| 国产成人亚洲精品91专区高清 | 中文字幕一区二区免费| 亚洲最大黄色网址| 亚洲第一网站男人都懂| 免费无码中文字幕A级毛片| 亚洲成av人片天堂网无码】| 337p日本欧洲亚洲大胆裸体艺术| 青娱分类视频精品免费2| 一级毛片a女人刺激视频免费| 亚洲视频小说图片| 亚洲国产精品毛片av不卡在线| 毛片无码免费无码播放|