企業應用架構模式學習筆記
by 零雨其蒙
2008-1-27
第一部分 表述
1 分層
1.1 三個基本層次
三層架構:
表現層:表現邏輯處理用戶與軟件間的交互。主要職責是:
ü 向用戶顯示信息
ü 把從用戶那里獲得的信息解釋成領域層或數據源層上的各種動作。
數據源層:數據源邏輯主要關注與其他系統的交互,這些系統將代表應邀完成相關的任務。主要的數據源邏輯就是數據庫,它的主要職責是存儲持久數據。
領域層:領域邏輯(業務邏輯),它就是應用必須做的所有領域相關的工作:
ü 根據輸入數據或已有數據進行計算
ü 對從表現層輸入的數據進行驗證
ü 根據從表現層接收的命令來確定應該調度哪些數據源邏輯。
三層的關系:領域層是核心!表現層是系統對外提供服務的外部接口;數據源層是系統使用外部服務的接口。
零雨其蒙批注:這段話實在是經典,表現層作為對外提供服務的接口,指明了外部如何使用該系統的契約,這樣領域層可以作為Web Service暴露給外部,可以是REST風格的服務接口,抑或作為另一個系統的數據源。而數據源層作為領域層訪問外部服務的接口,指明了該系統如何使用其它服務的契約,這些服務就可能是數據庫服務,消息服務,甚至是另一個可以提供數據的系統,我想這層之下的層次叫做EIS的原因吧。
這也恰恰提醒我們,表現層接口和數據源層(我還是覺得叫數據訪問層比較好)接口并不直接相關,因此在設計時不要將這兩個接口進行簡單的設計映射,表現層接口的契約與數據源層接口的契約簡單對應會造成系統不穩定,數據訪問層的變動將導致表現層接口的變動。另外,由于要記住,它們是為不同目的設計的!
分層結構依賴原則:領域層和數據源層絕對不要依賴于表現層。也就是說,在領域層和數據源層的代碼中,不要出現調用表現層代碼的情況。
區分邏輯層次的是否劃分正確的簡單測試原則:層次替換修改原則(注:我自己給起的名字)——假想向系統中增加一個完全不同的新層,例如為Web應用增加一個命令行界面層。如果這個過程中,發現需要重復實現某些功能,則說明可能有一些本應該在領域層實現的邏輯,現在在表現層實現了。類似的,你可以假想一下,將后臺數據庫更換成XML文件格式,看看情況又如何?
2 組織領域邏輯
事務腳本模式與領域模型模式。
范例:
核心問題是:對于同一給定的合同,不同種類的產品有不同的收入確認算法。計算收入確認的方法中必須先確定給定合同中產品的種類,然后應用正確的算法,之后再創建相應的收入確認對象[U1] (RevenueRecognition)來保存計算結果。
使用事務腳本計算收入確認
a Recognition Service:確認服務
calculateRecognitions(contractID):根據合同(contract)ID計算確認
findContract(contractID):向數據入口發送“查找合同”消息,根據合同ID查找合同,返回合同結果集
insert revenue recognitions:插入收入確認。
使用領域模型計算收入確認
利用了典型的策略模式(GoF),將對于不同產品的確認策略分離出來,以實現對于不同產品采取不同的計算確認策略。
class Contract{
private Product product;
public void setProduct(Product product){
this. product= product;
}
public Product getProduct(){
return this. product;
}
public void calculateRecogntions(){
getProduct().calculateRecogntions(this);
}
}
class Product{
private RecogntionStrategy recogntionStrategy;
public void set RecogntionStrategy (RecogntionStrategy recogntionStrategy){
this. recogntionStrategy = recogntionStrategy;
}
public RecogntionStrategy getRecogntionStrategy (){
return this. recogntionStrategy;
}
public void calculateRecogntions(Contract contract){
getRecogntionStrategy ().calculateRecogntions (contract);
}
}
2.1 服務層
概念:處理領域邏輯的常見方法是將領域層再細分成兩層。服務層獨立出來,置于底層的領域模型或表模塊之上。
職責:表現邏輯與領域層的交互完全通過服務層,就好像應用程序的API一樣。服務層是放置事務控制和安全等功能的好場所。
組成:最小化情況下,服務層只是一個外觀,所有實際的行為都在下層的對象中,服務層所做的只是將上層調用傳遞到更低層。此時,服務層提供一個更易于使用的API,因為它的方法通常根據用例來組織。該方式是Fowler最為推崇的方式。另外還有將服務層實現為一個事務腳本或使用控制器-實體模式。
3 映射到關系數據庫
3.1 架構模式
講了幾種入口(Gateway)模式后,Fowler指出:一種更好的方法是把領域模型和數據庫完全獨立,可以讓間接層完成領域對象和數據庫表之間的映射。這個數據映射器處理數據庫和領域模型之間所有的存取操作,并且允許雙方都能獨立變化。
零雨其蒙注解:目前采用Hiberante之類的O/RM框架就是實現該模式。
另外,Fowler不推薦把入口(Gateway)用作領域模型的首選持久化機制。
即使使用數據映射器作為首選持久化機制,還是可以使用數據入口來封裝被視為外部接口的表或者服務。