企業(yè)應(yīng)用架構(gòu)模式學(xué)習(xí)筆記
by 零雨其蒙
2008-1-27
第一部分 表述
1 分層
1.1 三個基本層次
三層架構(gòu):
表現(xiàn)層:表現(xiàn)邏輯處理用戶與軟件間的交互。主要職責(zé)是:
ü 向用戶顯示信息
ü 把從用戶那里獲得的信息解釋成領(lǐng)域?qū)踊驍?shù)據(jù)源層上的各種動作。
數(shù)據(jù)源層:數(shù)據(jù)源邏輯主要關(guān)注與其他系統(tǒng)的交互,這些系統(tǒng)將代表應(yīng)邀完成相關(guān)的任務(wù)。主要的數(shù)據(jù)源邏輯就是數(shù)據(jù)庫,它的主要職責(zé)是存儲持久數(shù)據(jù)。
領(lǐng)域?qū)?/span>:領(lǐng)域邏輯(業(yè)務(wù)邏輯),它就是應(yīng)用必須做的所有領(lǐng)域相關(guān)的工作:
ü 根據(jù)輸入數(shù)據(jù)或已有數(shù)據(jù)進(jìn)行計算
ü 對從表現(xiàn)層輸入的數(shù)據(jù)進(jìn)行驗(yàn)證
ü 根據(jù)從表現(xiàn)層接收的命令來確定應(yīng)該調(diào)度哪些數(shù)據(jù)源邏輯。
三層的關(guān)系:領(lǐng)域?qū)邮呛诵模”憩F(xiàn)層是系統(tǒng)對外提供服務(wù)的外部接口;數(shù)據(jù)源層是系統(tǒng)使用外部服務(wù)的接口。
零雨其蒙批注:這段話實(shí)在是經(jīng)典,表現(xiàn)層作為對外提供服務(wù)的接口,指明了外部如何使用該系統(tǒng)的契約,這樣領(lǐng)域?qū)涌梢宰鳛閃eb Service暴露給外部,可以是REST風(fēng)格的服務(wù)接口,抑或作為另一個系統(tǒng)的數(shù)據(jù)源。而數(shù)據(jù)源層作為領(lǐng)域?qū)釉L問外部服務(wù)的接口,指明了該系統(tǒng)如何使用其它服務(wù)的契約,這些服務(wù)就可能是數(shù)據(jù)庫服務(wù),消息服務(wù),甚至是另一個可以提供數(shù)據(jù)的系統(tǒng),我想這層之下的層次叫做EIS的原因吧。
這也恰恰提醒我們,表現(xiàn)層接口和數(shù)據(jù)源層(我還是覺得叫數(shù)據(jù)訪問層比較好)接口并不直接相關(guān),因此在設(shè)計時不要將這兩個接口進(jìn)行簡單的設(shè)計映射,表現(xiàn)層接口的契約與數(shù)據(jù)源層接口的契約簡單對應(yīng)會造成系統(tǒng)不穩(wěn)定,數(shù)據(jù)訪問層的變動將導(dǎo)致表現(xiàn)層接口的變動。另外,由于要記住,它們是為不同目的設(shè)計的!
分層結(jié)構(gòu)依賴原則:領(lǐng)域?qū)雍蛿?shù)據(jù)源層絕對不要依賴于表現(xiàn)層。也就是說,在領(lǐng)域?qū)雍蛿?shù)據(jù)源層的代碼中,不要出現(xiàn)調(diào)用表現(xiàn)層代碼的情況。
區(qū)分邏輯層次的是否劃分正確的簡單測試原則:層次替換修改原則(注:我自己給起的名字)——假想向系統(tǒng)中增加一個完全不同的新層,例如為Web應(yīng)用增加一個命令行界面層。如果這個過程中,發(fā)現(xiàn)需要重復(fù)實(shí)現(xiàn)某些功能,則說明可能有一些本應(yīng)該在領(lǐng)域?qū)訉?shí)現(xiàn)的邏輯,現(xiàn)在在表現(xiàn)層實(shí)現(xiàn)了。類似的,你可以假想一下,將后臺數(shù)據(jù)庫更換成XML文件格式,看看情況又如何?
2 組織領(lǐng)域邏輯
事務(wù)腳本模式與領(lǐng)域模型模式。
范例:
核心問題是:對于同一給定的合同,不同種類的產(chǎn)品有不同的收入確認(rèn)算法。計算收入確認(rèn)的方法中必須先確定給定合同中產(chǎn)品的種類,然后應(yīng)用正確的算法,之后再創(chuàng)建相應(yīng)的收入確認(rèn)對象[U1] (RevenueRecognition)來保存計算結(jié)果。
使用事務(wù)腳本計算收入確認(rèn)
a Recognition Service:確認(rèn)服務(wù)
calculateRecognitions(contractID):根據(jù)合同(contract)ID計算確認(rèn)
findContract(contractID):向數(shù)據(jù)入口發(fā)送“查找合同”消息,根據(jù)合同ID查找合同,返回合同結(jié)果集
insert revenue recognitions:插入收入確認(rèn)。
使用領(lǐng)域模型計算收入確認(rèn)
利用了典型的策略模式(GoF),將對于不同產(chǎn)品的確認(rèn)策略分離出來,以實(shí)現(xiàn)對于不同產(chǎn)品采取不同的計算確認(rèn)策略。
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 服務(wù)層
概念:處理領(lǐng)域邏輯的常見方法是將領(lǐng)域?qū)釉偌?xì)分成兩層。服務(wù)層獨(dú)立出來,置于底層的領(lǐng)域模型或表模塊之上。
職責(zé):表現(xiàn)邏輯與領(lǐng)域?qū)拥慕换ネ耆ㄟ^服務(wù)層,就好像應(yīng)用程序的API一樣。服務(wù)層是放置事務(wù)控制和安全等功能的好場所。
組成:最小化情況下,服務(wù)層只是一個外觀,所有實(shí)際的行為都在下層的對象中,服務(wù)層所做的只是將上層調(diào)用傳遞到更低層。此時,服務(wù)層提供一個更易于使用的API,因?yàn)樗姆椒ㄍǔ8鶕?jù)用例來組織。該方式是Fowler最為推崇的方式。另外還有將服務(wù)層實(shí)現(xiàn)為一個事務(wù)腳本或使用控制器-實(shí)體模式。
3 映射到關(guān)系數(shù)據(jù)庫
3.1 架構(gòu)模式
講了幾種入口(Gateway)模式后,Fowler指出:一種更好的方法是把領(lǐng)域模型和數(shù)據(jù)庫完全獨(dú)立,可以讓間接層完成領(lǐng)域?qū)ο蠛蛿?shù)據(jù)庫表之間的映射。這個數(shù)據(jù)映射器處理數(shù)據(jù)庫和領(lǐng)域模型之間所有的存取操作,并且允許雙方都能獨(dú)立變化。
零雨其蒙注解:目前采用Hiberante之類的O/RM框架就是實(shí)現(xiàn)該模式。
另外,Fowler不推薦把入口(Gateway)用作領(lǐng)域模型的首選持久化機(jī)制。
即使使用數(shù)據(jù)映射器作為首選持久化機(jī)制,還是可以使用數(shù)據(jù)入口來封裝被視為外部接口的表或者服務(wù)。
[U1]相當(dāng)于《結(jié)算方式確認(rèn)通知書》???