MVC的關(guān)鍵是給我們提出了一個(gè)原則:怎么對(duì)項(xiàng)目進(jìn)行合理的關(guān)注點(diǎn)分離攻询。Model負(fù)責(zé)業(yè)務(wù)領(lǐng)域,controller負(fù)責(zé)對(duì)model進(jìn)行工作安排州弟,而view則負(fù)責(zé)門(mén)面钧栖,怎么讓外面的人看的滿(mǎn)意。
但是MVC只提供了3層呆馁,對(duì)于再?gòu)?fù)雜的應(yīng)用沒(méi)有提供足夠的組織和關(guān)注點(diǎn)分離的原則了桐经,這個(gè)時(shí)候我們來(lái)看下Clean Architecture。
本文為系列文章的第七篇浙滤,完成的目錄請(qǐng)查看Clean Architecture
The Clean Architecture
Clean Architecture是Uncle Bob Martin在2012年寫(xiě)的阴挣,文章中收集了一系列類(lèi)似的架構(gòu),它們的共同點(diǎn)如下:
-
框架無(wú)關(guān)(Independent of Frameworks)
這些架構(gòu)沒(méi)有依賴(lài)于一些已經(jīng)存在的庫(kù)或軟件纺腊,帶來(lái)的好處是:你無(wú)需要去硬滿(mǎn)足框架給你制定的條條框框畔咧,框架本身只是你的一個(gè)工具。
-
可測(cè)性(Testable)
業(yè)務(wù)邏輯可以在沒(méi)有UI揖膜,Database誓沸,Web Server 或任何外部元素的情況下測(cè)試
-
UI無(wú)關(guān)(Independent of UI)
UI可以在不改變業(yè)務(wù)邏輯的情況下快速改變,譬如可以將Web UI替換為Console UI
-
數(shù)據(jù)庫(kù)無(wú)關(guān)(Independent of Database)
我們可以替換后端的存儲(chǔ)壹粟,從mysql到nosql拜隧,不影響我們的業(yè)務(wù)邏輯
-
無(wú)外部依賴(lài)(Independent of any external agency)
我們核心的業(yè)務(wù)邏輯對(duì)任何的外部依賴(lài)都是無(wú)感的宿百,或者說(shuō)我們的業(yè)務(wù)邏輯只關(guān)心領(lǐng)域邏輯。
框架無(wú)關(guān)(Independent of Frameworks)
PHP社區(qū)現(xiàn)在異常的活躍洪添,各種框架層出不窮垦页,Laravel,Silex等干奢,沒(méi)準(zhǔn)昨天還流行的框架痊焊,今天就又出了一個(gè)更好的,因此如果你將自己的核心邏輯綁定到某個(gè)框架上忿峻,那么sorry薄啥,框架的升級(jí)或者替換摇零,你都需要重寫(xiě)你代碼了发乔。
可測(cè)性(Testable)
測(cè)試的編寫(xiě)跟項(xiàng)目大小無(wú)關(guān),不能因?yàn)轫?xiàng)目大而沒(méi)有時(shí)間去寫(xiě)測(cè)試用例炒辉,也不能因?yàn)轫?xiàng)目小太簡(jiǎn)單不去寫(xiě)測(cè)試绰寞。測(cè)試的編寫(xiě)隨著項(xiàng)目的不斷重構(gòu)赘艳,它的意義會(huì)越來(lái)越大,因?yàn)槲覀儫o(wú)法保證代碼的編寫(xiě)都是一個(gè)人克握,每次的修改都不會(huì)改變?cè)瓉?lái)的功能蕾管,這個(gè)時(shí)候測(cè)試用例的作用就凸顯出來(lái)了,每次修改后菩暗,都運(yùn)行case掰曾,保證功能的正確性。
數(shù)據(jù)庫(kù)無(wú)關(guān)(Independent of Database)
數(shù)據(jù)庫(kù)無(wú)關(guān)這點(diǎn)在實(shí)際工作中可能不是那么重要停团,因?yàn)槊總€(gè)公司都有自己的存儲(chǔ)服務(wù)旷坦,像我們公司后端持久化存儲(chǔ)一直是mysql,或者說(shuō)存儲(chǔ)一直是兼容mysql的sql的佑稠,關(guān)注存儲(chǔ)的適配有專(zhuān)門(mén)的團(tuán)隊(duì)來(lái)做秒梅,應(yīng)用這邊看到的一直就是mysql。
但是對(duì)于開(kāi)源軟件就不是了舌胶,我們需要考慮后端存儲(chǔ)的變化捆蜀,需要能滿(mǎn)足各個(gè)存儲(chǔ)。
無(wú)外部依賴(lài)(Independent of any external agency)
通過(guò)composer我們能很快利用社區(qū)的開(kāi)源庫(kù)幔嫂,加速我們應(yīng)用的開(kāi)發(fā)辆它。但是社區(qū)活躍帶來(lái)的問(wèn)題是,庫(kù)的出現(xiàn)快履恩,消失的也快锰茉。因此我們?cè)陂_(kāi)發(fā)中,必須要考慮盡量減少對(duì)外部庫(kù)的依賴(lài)切心,一個(gè)方法就是之前介紹的適配器模式飒筑。
The Onion Architecture
The Onion Architecture最初是由Jeffrey Palermo提出的片吊,是clean architecture的一個(gè)變種。
Palermo將軟件的分層比喻成洋蔥一樣的一層一層:從里面往外一層一層的看协屡,每一層都依賴(lài)著內(nèi)層定鸟,但是內(nèi)層卻不依賴(lài)于外層,通過(guò)一個(gè)圖來(lái)認(rèn)識(shí)下:
傳統(tǒng)的應(yīng)用開(kāi)發(fā)中著瓶,應(yīng)用是以數(shù)據(jù)庫(kù)為中心設(shè)計(jì)的,先確定數(shù)據(jù)庫(kù)中每個(gè)表的結(jié)構(gòu)啼县,然后應(yīng)用在基于數(shù)據(jù)進(jìn)行設(shè)計(jì)材原,如果將其剝離出來(lái),整個(gè)系統(tǒng)變的支零破碎季眷。
在Onion Architecture中余蟹,應(yīng)用核心是領(lǐng)域模型,完全和數(shù)據(jù)庫(kù)解耦子刮,在整個(gè)應(yīng)用中威酒,數(shù)據(jù)庫(kù)只是應(yīng)用需要的一個(gè)組件,我們可以完全替換存儲(chǔ)挺峡,而不影響整個(gè)應(yīng)用邏輯葵孤。
領(lǐng)域模型和領(lǐng)域服務(wù)
在Onion Architecture中最核心是領(lǐng)域模型層,該層只包含了領(lǐng)域模型橱赠,彼此之間進(jìn)行交互尤仍,不涉及領(lǐng)域之外的邏輯,在領(lǐng)域模型之外是領(lǐng)域服務(wù)層狭姨,包括了工廠(factories)宰啦、倉(cāng)庫(kù)(repositories)和其他的一些使用領(lǐng)域模型的服務(wù)。
領(lǐng)域模型和領(lǐng)域服務(wù)合起來(lái)構(gòu)成了整個(gè)應(yīng)用的核心饼拍。應(yīng)用其他所有層都依賴(lài)于核心的領(lǐng)域模型和領(lǐng)域服務(wù)赡模。
應(yīng)用服務(wù)層
應(yīng)用層包含了具體的應(yīng)用的實(shí)現(xiàn),以MVC為例子:應(yīng)用層就是controller师抄。應(yīng)用層應(yīng)該只負(fù)責(zé)啟動(dòng)我們的應(yīng)用漓柑,不會(huì)再被其他層依賴(lài)了。應(yīng)用層只是用來(lái)調(diào)用我們內(nèi)存的個(gè)領(lǐng)域服務(wù)和領(lǐng)域模型叨吮,我們能很方便的替換應(yīng)用層欺缘。
我們可能感慨是使用的Symfony,但是后來(lái)要轉(zhuǎn)換為L(zhǎng)aravel挤安,如果我們核心設(shè)計(jì)的好谚殊,應(yīng)該是很方便就能切換過(guò)去的。
用戶(hù)接口
通過(guò)用戶(hù)接口UI蛤铜,我們將我們應(yīng)用的核心領(lǐng)域?qū)ο笳宫F(xiàn)給用戶(hù)嫩絮,由于沒(méi)有其他層依賴(lài)于UI了丛肢,因此我們無(wú)壓力的替換模型語(yǔ)言,使用新的js框架什么的剿干,so _
基礎(chǔ)設(shè)施
該層也是在最外層蜂怎,主要是給領(lǐng)域?qū)犹峁?shù)據(jù)的存取,通過(guò)他來(lái)獲取數(shù)據(jù)置尔,數(shù)據(jù)可能是數(shù)據(jù)庫(kù)里杠步,也可能是網(wǎng)絡(luò),或者其他地方榜轿,該層使我們整個(gè)應(yīng)用的數(shù)據(jù)提供方幽歼。
基礎(chǔ)層依賴(lài)于領(lǐng)域服務(wù)和領(lǐng)域?qū)樱驗(yàn)轭I(lǐng)域?qū)雍皖I(lǐng)域模型給出了基礎(chǔ)層必須實(shí)現(xiàn)的契約(contract)谬盐,基礎(chǔ)層來(lái)實(shí)現(xiàn)這些接口給領(lǐng)域?qū)犹峁?shù)據(jù)甸私。
本節(jié)只是對(duì)clean architecture做了一個(gè)概述,下面會(huì)對(duì)clean architecture的5個(gè)特點(diǎn)展開(kāi)具體的討論飞傀。
這是The Clean Architecture in PHP的第七篇皇型,你的鼓勵(lì)是我繼續(xù)寫(xiě)下去的動(dòng)力,期待我們共同進(jìn)步砸烦。