项目架构之传统三层架构和领域模型三层架构
一、架構(gòu)之傳統(tǒng)三層架構(gòu)
傳統(tǒng)三層架構(gòu)是一種軟件架構(gòu),是一種典型的、基于貧血模型的、面向過程的JavaWeb分層方式。該架構(gòu)分為以下三個層次:
分層的目的是為了解耦和明確責(zé)任。開發(fā)人員可以只關(guān)心自己所負(fù)責(zé)的那一層,因為他只需要知道上一層提供了哪些接口,從而利用這些接口進(jìn)行編程。而上一層的開發(fā)人員在不改變接口的情況下,可以任意地替換具體的實(shí)現(xiàn),從而實(shí)現(xiàn)松耦合。
相比更傳統(tǒng)的架構(gòu),三層架構(gòu)有著明顯的優(yōu)勢,但也有不可忽視的缺點(diǎn)。初期的JavaWeb在JSP內(nèi)同時進(jìn)行數(shù)據(jù)庫讀寫、業(yè)務(wù)邏輯處理和頁面渲染,簡單而暴力。而今的架構(gòu),在JSP之上增加了一個處理業(yè)務(wù)邏輯的中間層和一個封裝了數(shù)據(jù)庫操作的數(shù)據(jù)訪問層,毫無疑問造成了代碼量的大幅度上升和效率的下降。
本項目中,Mybatis承擔(dān)數(shù)據(jù)訪問的責(zé)任;SpringMVC包攬了頁面渲染和請求調(diào)度;Spring的IoC和AOP組成了整個項目的支架;Spring的事務(wù)控制為業(yè)務(wù)邏輯層的一致性提供了強(qiáng)有力的保障。
不同的語言、不同的框架對三層架構(gòu)有不同的演繹,但殊途同歸,業(yè)務(wù)數(shù)據(jù)的流向是一致的。下面以一個點(diǎn)菜的例子來示范這一點(diǎn):
二、架構(gòu)之領(lǐng)域模型架構(gòu)
領(lǐng)域模型的概念源于2004年出版的經(jīng)典著作《Domain-Driven Design –Tackling Complexity in the Heart of Software》(《領(lǐng)域驅(qū)動設(shè)計:軟件核心復(fù)雜性應(yīng)對之道》,簡稱DDD)。所謂領(lǐng)域,即軟件所關(guān)注的主題區(qū)域:
每個軟件程序的目的都是為了執(zhí)行某項活動,或是滿足用戶的某種需求。用戶會把軟件程序應(yīng)用于某個主題區(qū)域,這個區(qū)域就是軟件的領(lǐng)域。一些領(lǐng)域涉及物質(zhì)世界,例如機(jī)票預(yù)訂程序的領(lǐng)域中包括飛機(jī)乘客在內(nèi)。有些領(lǐng)域則是無形的,例如會計程序的金融領(lǐng)域。——摘自《領(lǐng)域驅(qū)動設(shè)計》第一章
該著作提出,設(shè)計軟件分為兩個步驟:
基于此,DDDSample官網(wǎng)提出了另一種三層架構(gòu):
如圖,該架構(gòu)分為界面(Interfaces)、應(yīng)用(Application)和領(lǐng)域(Domain)三層,以及一個基礎(chǔ)設(shè)施(Infrastructure),是一種基于充血模型的、面向?qū)ο蟮姆謱臃绞?/span>。其各層職責(zé)如下:
2.1、界面層(Interface)
負(fù)責(zé)所有與外部系統(tǒng)的交互,包括WebService、RMI或REST等。包括外觀(Facade)、裝配(Assembler)和數(shù)據(jù)傳輸對象(DTO)三類組件:
2.2、應(yīng)用層(Application)
應(yīng)用層的主要組件就是Service,其粒度與傳統(tǒng)三層架構(gòu)的service一致。差別在于,傳統(tǒng)三層架構(gòu)的service層負(fù)責(zé)業(yè)務(wù)邏輯的處理,而領(lǐng)域模式三層架構(gòu)的service只負(fù)責(zé)將業(yè)務(wù)委派給領(lǐng)域?qū)ο筮M(jìn)行處理。
2.3、領(lǐng)域?qū)?#xff08;Domain)
這一層是整個軟件的核心,幾乎包括了所有的業(yè)務(wù)邏輯。他包括了Entity(實(shí)體)、Value Object(值對象)、Domain Event(領(lǐng)域事件)和Repository(倉儲)等領(lǐng)域組件。下面以時下很火的共享自行車為例來簡單解釋這幾個組件:
舉個栗子,當(dāng)我們希望對每一輛共享自行車進(jìn)行管理時,他應(yīng)該被設(shè)計為實(shí)體,有唯一編號作為標(biāo)識,有顏色、重量、價格、品牌等屬性,有位置狀態(tài)、使用狀態(tài),有租賃行為。當(dāng)其被租賃時,其位置狀態(tài)和使用狀態(tài)可能發(fā)生改變。
同樣是共享自行車,如果我們的系統(tǒng)只為了統(tǒng)計各地區(qū)各品牌自行車的使用情況,即我們只關(guān)心他是什么,而不關(guān)心他是誰,那么他應(yīng)該被設(shè)計為值對象。
2.4、基礎(chǔ)設(shè)施(Infrastructure)
作為基礎(chǔ)設(shè)施,Infrastructure負(fù)責(zé)給三層架構(gòu)提供支持。所有與具體平臺、框架相關(guān)的實(shí)現(xiàn)都會在這一層實(shí)現(xiàn),以免影響三層架構(gòu)職責(zé)的純粹性、以及污染領(lǐng)域模型。對象持久化的具體實(shí)現(xiàn)也放在基礎(chǔ)設(shè)施里。
三、傳統(tǒng)三層架構(gòu) VS 領(lǐng)域模型架構(gòu)
從領(lǐng)域模型架構(gòu)各層的職責(zé)可以看出,他和傳統(tǒng)三層架構(gòu)最大的差別在于,領(lǐng)域模型架構(gòu)的業(yè)務(wù)邏輯包含在領(lǐng)域模型里,而傳統(tǒng)三層架構(gòu)的業(yè)務(wù)邏輯在Service層。為了實(shí)現(xiàn)這一點(diǎn),領(lǐng)域模型還引入了在Javascript和ActionScript中常見的事件機(jī)制;而傳統(tǒng)三層架構(gòu)中,領(lǐng)域模型的屬性和行為嚴(yán)格分離,變成了POJO和Service。
個人認(rèn)為,兩種架構(gòu)的出發(fā)點(diǎn)是相同的,一樣是先挖掘領(lǐng)域概念,然后建模,再根據(jù)模型進(jìn)行設(shè)計。差別在于,當(dāng)業(yè)務(wù)邏輯的復(fù)雜程度在單個開發(fā)人員或單個團(tuán)隊的把控能力范圍之內(nèi)時,采用面向過程的傳統(tǒng)三層架構(gòu)可以很快地完成建模工作,并開始業(yè)務(wù)邏輯的設(shè)計;而當(dāng)業(yè)務(wù)邏輯復(fù)雜到一定程度時,則有必要花更多的時間用在建模上,去抽取模型的行為,去設(shè)計和關(guān)聯(lián)模型事件,以期在后續(xù)迭代中,開發(fā)人員只需面對一個個可以清晰地理解的領(lǐng)域?qū)ο?#xff0c;而不是一坨動輒上千行的某業(yè)務(wù)行為的邏輯代碼。
綜上考慮,大部分web系統(tǒng)可以采用傳統(tǒng)三層架構(gòu)。
四、模型的形態(tài)
不同的架構(gòu)、不同的層、不同的應(yīng)用場景中有著不一樣的建模需求,因此表述相同概念的模型可能會有不同的“形態(tài)”,例如:
四、MVC模式
跟架構(gòu)密切相關(guān)的另一個詞匯是MVC模型,即Model-View-Controller模式。MVC模式是一種設(shè)計軟件的模式,不是一種架構(gòu)。在傳統(tǒng)三層架構(gòu)中,MVC的理念被應(yīng)用在表現(xiàn)層:View提交請求數(shù)據(jù)給Controller,Controller返回數(shù)據(jù)用于渲染View,兩者之間以Model(VO - ViewModel)的形式進(jìn)行通信。如下圖:
參考文章地址:https://my.oschina.net/mzdbxqh/blog/865046
?
總結(jié)
以上是生活随笔為你收集整理的项目架构之传统三层架构和领域模型三层架构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 论文浅尝 | 一日看尽长安花--NLP可
- 下一篇: 技术动态 | eBay开源分布式知识图谱