星期六, 5月 14, 2005

(draft v2) Best Practice for Struts+Hibernate+Spring

最近又看了一本 Pro Spring,喔~ 裡面的第十一章 (Designing and implementating spring-based applications) 真是太棒囉!很多建議都相當的實用,解決了許多困惑我很久的疑問。這樣子差不多可以整理出一個通用的開發架構了:

o J2EE without EJB
採用 Struts + Hibernate +Spring 三個 framework 開發專案,每個framework都提供較 j2ee 更簡單、更快速、更open的實作。
  • Struts 提供 presentation layer 的各項服務
  • Hibernate 提供 domain layer 的 persistence 及 query 服務
  • Spring 提供 transaction/mail/remoting... 等等 middle-ware 的服務
o Writing unit test for everything
Struts Action/ActionForm, Hibernate DAO, Spring Service.... etc 從上到下所有的 java code 都依循 TDD 的方式開發。目前除了 jsp 之外,全部都要寫 unit test。

o 4 layers
  • Presentation Layer - 與使用者互動
  • Application Service Layer - 此層可明確表示 use case / user story / user requirement
  • Domain Layer - domain problem mapping as domain objects interaction.
  • Persistence Layer - 負責物件的儲存及查詢. (物件的中間生命週期)
o 保持 domain layer 乾淨
  • no DAO
    • 進入 domain layer 前,先將資料轉換為 domain object,無論是從 database 來或是使用者輸入。
    • domain object 間的 association,如果需要從 database query,盡可能改用 ORM 直接做associate ,而不是再透過 DAO 才連結。(除非 performance 的考量)
  • no Service
    • domain object 不應與任何 framework, container, context, enviroment... etc 等相關。所有存在於Domain Layer 的物件僅僅是互相連結的 POJO。
o Domain Object >= Persistence Object
  • Domain Object is not nessasary identical with Persistence Object(PO). just choose domain objects that need to persistence and query as PO.
  • All Persistence Object's getter/setter should be in default package scope.
o Design Domain Object fine grain and immutable
  • Do not afraid introduceing new Class.
  • Prefer immutable object. Immutable Object enforce you mapping domain problem to domain object correctly, and reduce maintain effort. Only Persistence Object has mutable characteristic.
  • no getter/setter. Object's property is hidden and only expose behavior to public.
  • no Singleton and no static. If you find something can apply singleton pattern, or design as static. It may be not belong to domain layer.
o Domain Object 跨全域
  • Domain Object 會傳到 presentation layer 與使用者互動,會傳到 application layer 使用 middle-ware 服務、會扮演 PO 進入 persistence layer 儲存。
  • 安全地跨全域的關鍵在於 Immutable。
  • DTO is non-sense.
o Classify Root of Domain Object in domain layer
  • ex. A Car has engine/wheel... etc. A engine can not work or sell directly. so typically Car class is Root of car/engine/wheel.
  • ex. An engine Factory produce various engines and sell them to down-stream factory. Obviously now the engine is Root class for this domain.
o Service Layer:
  • thin business logic
  • coordinate:
    • Root of Domain Object
    • DAO
    • Other middle-ware service (mail/remoting/transaction)
  • each method is unit of work of user's single operation
  • method boundary is transaction boundary, declare in Spring.
  • Spring managed resources are all in this layer.
  • Apply IoC in this layer heavily to make test easier. (flexible design)
  • Every service is a interface and pair with at least one implementation: FooService/FooServiceImpl
o Persistence Layer:
  • Not all database table has it's own DAO, only Root of Domain Object has DAO
  • See Hibernate 3 Reference chap. 7 to choose best association for your ORM
  • Efficiently use Hibernate's optimistic lock feature for concurrecy issue.
  • Efficiently use Hibernate's lazy/cache/fetch join technique to improve ORM performance
  • All POs have an primary key: 'Long id'. DO NOT use compose key !
  • All POs' getter/setter scope is package default (private is better)
  • Perfer HibernateTemplate and JdbcTemplate, with this we don't require additional interface for DAOs.
o Struts ActionForm:
  • ActionForm will be populated from Domain Object for user input.
  • After user input, the ActionForm should convert user's input back to domain object if possible.
  • It's ok that treat ActionForm as Domain Object and transfer into service layer, but use with care because ActionForm is highly mutable. If you want to protect Domain Layer and reuse ActionForm's code, Just let ActionForm implement Domain Object interface.
o Struts Action:
  • each Action only call one method of a single service. (because of transaction boundary)
  • Action's responsibility is to coordinate Invoking service method, ActionForm population, ActionForward flow, and compose ActionMessage... etc, nothing more.
  • does nothing about business logic.
o Design Business Exception:
  • All business exceptions are checked and user recoverable. if the exception is user un-recoverable, it should be classified as RuntimeException
  • All business exception should extends 'BusinessException', the Root of all business exceptions
  • If you want your business exception support i18n, use 'ResourceKeyBusinessException', which extends from 'BusinessException'
  • Each module only has one its own Root business exception, and all rest of exceptions for this module should extends its own Root business exception
  • This is checked exception, but you will not try to catch it except in Struts Action. business exception is 'user' recoverable, so it should always throw away until Struts Action. Struts Action catch Business Exception, convert to meaningful message and forward user to error page.
好像越寫越多... 看起來亂亂的... 而且英文佔了一大半 -_-;
啊,就先這樣就好了,以後有空在補。

4 Comments:

At 5:31 下午, Anonymous 匿名 said...

xexex I was just searching blogs for information on web pages , and I can across (draft v2) Best Practice for Struts+Hibernate+Spring .
I also have a web pages site. You might find it helpful.
You should check it out sometime if you get a chance :-)

 
At 4:29 上午, Anonymous 匿名 said...

Hi xexex, taking a little time today to see what Residual Cash Flow will send me to that is interesting. (draft v2) Best Practice for Struts+Hibernate+Spring looks interesting and is a great read. Will also try Residual Cash Flow in my e-travels. Have a super day!

 
At 7:27 下午, Anonymous 匿名 said...

Hi xexex, it’s late in the evening, quiet and peaceful. This is good computer time for me. I thought I would check on Global Business and see what came up. (draft v2) Best Practice for Struts+Hibernate+Spring is something that is interesting to many people. I will also spend a little time checking on Global Business. Getting late, have a good evening.

 
At 6:39 上午, Anonymous 匿名 said...

Hi xexex, taking a little time today to see what Permanent Income will send me to that is interesting. (draft v2) Best Practice for Struts+Hibernate+Spring looks interesting and is a great read. Will also try Permanent Income in my e-travels. Have a super day!

 

張貼留言

<< Home