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

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

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

    jojo's blog--快樂憂傷都與你同在
    為夢想而來,為自由而生。 性情若水,風起水興,風息水止,故時而激蕩,時又清平……
    posts - 11,  comments - 30,  trackbacks - 0

    [原文:http://javamen.blogdriver.com/javamen/299858.html]

    FrankSoo是我的項目經理。前段時間公司決定作個新的J2EE二次開發平臺,以替換公司原有的開發平臺。公司讓FrankSoo和我組成平臺開發項目組,FrankSoo擔任項目經理?,F在這個平臺整合開發階段已經結束,進入項目應用階段。下面是我們的整合工作小結,介紹一下我們在工作中遇到的問題,以及我們選擇的解決方案.


    1、架構的選擇

    首先,我們都同意以我們現有的能力,沒有足夠的時間和資源自行開發一套完整的平臺。在已有的眾多開源項目中選擇若干優秀的項目進行整合,才可能按時完成項目,達到項目目的。
    但是在平臺項目開始前,我們對平臺的技術架構有各自的構想。FrankSoo原來的構想是Struts+Spring+Hibernate,而我的構想是Tapestry+Hibernate。
    不過FrankSoo非常open,在我向他演示了Tapestry的經典范例workbench,介紹了Tapestry基于組件的編程方式之后,他同意選用Tapestry作為實現Web展現層的框架。我想FrankSoo以前的Struts開發經驗(painful)也是他做出這個決定的因素之一。 FrankSoo gave me a nice introduction of Spring Framework. Wow, what an amazing framework! IOC, Declarative Transaction Support, Hibernate Session Management, Hibernate DAO Support… These features are just what we need for a middle tire container.

    至于Hibernate,這個最成功的開源ORM項目,我們都投了它一票^_^
    最后我們確定平臺的技術架構是Tapestry+Spring+Hibernate.

    2、架構整合

    最初的平臺架構借鑒了一篇介紹如何集成Tapestry與Spring的文章[1]中提到的架構:

    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萬條記錄),確定平臺不存在性能問題。

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

    3、困擾我們的問題

    在實現例子和現在的項目應用過程中,我們發現了若干頭疼的問題,有的解決了,有的還沒有。

    問題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 model直接傳到Web層。下面是修改后的架構圖(呵呵,修改了別人的圖[2])。

    問題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>標簽,生成抽象基類,我們繼承這些自動生成的基類,添加業務方法。

    問題3:Model driven or Data driven?

    采用Model driven還是Data driven的方式大家有過熱烈的討論。我們主要是受到Rod Johnson[3]的影響,采用了Data driven的方式。先作數據庫設計,生成庫表,然后用Middlegen反向生成Hibernate映射文件和Entity及DAO。但是我們在進入項目應用之后發現這種方法有兩個問題:

    a) 數據庫設計僅說明了系統要管理的靜態數據,我們還是得作面向對象分析,以反映系統的動態行為。特別是當系統的業務不僅僅是簡單的CRUD操作時,這個問題更嚴重。
    b) 數據庫設計為了優化性能,可能會把好幾個應該是單獨實體的數據放入一個實體中。這樣如果直接把這種極粗粒度實體映射成Entity類,那簡直是不可接受的。面向對象的分析設計模型得到的類都是相當細粒度的。這種情況還得作面向對象的分析,明確到底這個粗粒度的大表應該映射成那幾個細粒度的對象。

    或許我們應該試試Model driven,用AndroMDA生成domain model,Hibernate DAO,Hibernate mapping,數據庫表,簡單的Service和前臺的Tapestry頁面。

    問題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的業務方法, 以獲得數據.

    問題5:Use case logic 和domain logic 如何區分?

    Service負責use case logic,domain model負責domain logic。這樣的劃分看起來很好,實現起來就很麻煩。如何確定什么是use case logic,什么是domain logic?TBD.


    問題6:Service粒度如何確定?

    這個問題真是很煩,原先考慮使用usecase controller的方式,每個usecase對應一個Service,但是發現這樣復用性太低,而且好多地方必須復用相同的功能

    另一種方法是用package level service,每個package作個service,這樣倒是可以重用,但是感覺太死了,不好。

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

    問題7:權限如何設定?如何檢查?

    權限設定也是個頭疼的問題。我們本想是按照use case設定權限,每個用例一個權限。在角色設定的時候直接處理的都是業務意義非常明確的權限。但是在權限驗證過程中發現了問題:如果在Service的方法中驗證權限,而且這個方法在多個用例中用到(復用Service),那么這個Service的方法就需要檢查多個權限; 如果每個Service方法對應一個權限, 那么權限又太細了, 不像use case權限那樣代表一個完整的業務. 真的是很麻煩阿!TBD.
    Quake wang:問題1:要不要使用DTO?
    No DTO, 直接把domain object傳給Tapestry的web層,利用Tapestry提供強大的數據綁定和組件功能很方便


    問題2:Entity like domain model or rich domain model?
    domain model不包括復雜的domain logic, 只是作為一個data model bean, 再加上一些簡單的logic, 比如addChild的同時,設置child的parent此類簡單logic.


    問題3:Model driven or Data driven?
    這個對我來說不是什么大問題,個人習慣而已,我覺得無論是Model driven或者Data driven,對于相同的需求,2者最終的設計應該都是很類似的。我是從2邊同時考慮的,一邊做Model,一邊還要考慮數據庫的結構, 再進行相應的調整,用下來也沒有什么問題。沒有用代碼生成, 只是用Hibernate的Eclipse plugin (Hibernate Synchronizer)來幫我做一些code assist.


    問題4:Hibernate Session生命周期如何管理?
    目前沒有采用open session in view,也是和你們一樣,在Service里面準備好所有需要的對象。


    問題5:Use case logic 和domain logic 如何區分?
    由于domain model里面沒有什么domain logic,這個問題不存在.


    問題6:Service粒度如何確定?
    由于domain model里面沒有什么domain logic,所以Service的功能就切得很細,盡量重用,一個package可能有多個service, 感覺還好,沒有太死。

    問題7:權限如何設定?如何檢查?
    這個也是我沒有想好的問題, 因為不同的需求, 權限設定都不一樣,很難用AOP來做一個通用的aspect. 1. DAO的做法:
    我目前不是給每個domain object都做一個DAO, 而是整個系統就一個DAO (PersistenceManager), 里面只有create, update, delete entity這3個方法。另外寫一個DAO, 專門做查詢 (QueryManager), 用hibernate的named query做常用的查詢, 用criteria來做基于用戶輸入的動態查詢。不知道你們的做法是怎么樣?另外criteria 和 named query其實都是hardcode,object attribute name改變的時候,還得記得手工去修改這些代碼,unit test很難覆蓋到所有的criteria search 和 named query里面的代碼,這個是目前感覺不是很方便的地方。

    2. Spring 和 Tapestry的集成
    目前只是用Spring到service layer而已, Tapestry通過Global(扮演Service Locator的角色)這個對象來調用,在domain Tapestry這一層還是有很多dirty code, 其實也可以用AOP來解決。如果能夠像webwork2那樣,所有的action都可以通過從Spring獲得,即通過Spring獲得page
    listeners, 那會方便很多,不過Tapestry也有自己的類增強功能,好像有一定的沖突,目前沒有什么好的想法。

    順便推薦3個我在項目中使用的工具 (都是eclipse plugin):
    1. http://spindle.sourceforge.net 開發Tapestry的必備
    2. http://springui.sourceforge.net 寫Spring application context file的輔助好工具
    3. http://www.binamics.com/hibernatesynch/ Hibernate 開發的輔助好工具。

    posted on 2008-10-04 23:04 Blog of JoJo 閱讀(149) 評論(0)  編輯  收藏 所屬分類: Programming 相關

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(6)

    隨筆檔案

    文章分類

    文章檔案

    新聞分類

    新聞檔案

    相冊

    收藏夾

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产午夜不卡AV免费| 阿v视频免费在线观看| 国产性爱在线观看亚洲黄色一级片 | 亚洲AV成人无码久久WWW| 亚洲精品动漫免费二区| 亚洲中文字幕日本无线码| 日本三级2019在线观看免费| 亚洲伊人久久大香线焦| 18勿入网站免费永久| 亚洲熟妇AV一区二区三区宅男| 性xxxx视频播放免费| 亚洲无人区一区二区三区| 2020亚洲男人天堂精品| 午夜爱爱免费视频| 免费无毒a网站在线观看| 亚洲中文字幕无码爆乳av中文 | 国产亚洲精品AA片在线观看不加载| 精品久久久久久国产免费了| 国产卡二卡三卡四卡免费网址| 亚洲福利秒拍一区二区| 日本视频免费观看| 久久亚洲国产成人影院网站| 国产午夜无码片免费| 久久亚洲精品无码aⅴ大香| 成人免费午夜在线观看| 美女被爆羞羞网站免费| 亚洲精品无码Av人在线观看国产| 亚洲一区免费观看| 亚洲精品中文字幕| 亚洲日韩在线观看| 亚洲黄色片免费看| 狠狠入ady亚洲精品| 国产A在亚洲线播放| 日韩版码免费福利视频| 一区二区免费在线观看| 久久久久亚洲AV无码永不| 久久免费线看线看| 亚洲AV无码不卡在线播放| 成人免费视频69| 一区二区免费在线观看| 亚洲性猛交xx乱|