柚子快報(bào)激活碼778899分享:架構(gòu)簡(jiǎn)潔之道-5.整潔架構(gòu)
柚子快報(bào)激活碼778899分享:架構(gòu)簡(jiǎn)潔之道-5.整潔架構(gòu)
圖中的同心圓分別代表了軟件系統(tǒng)中的不同層次,通常越靠近中心,其所在的軟件層次就越高?;旧?,外層圓代表的是機(jī)制,內(nèi)層圓代表的是策略。當(dāng)然這其中有一條貫穿整個(gè)架構(gòu)設(shè)計(jì)的規(guī)則。
即它的依賴(lài)關(guān)系規(guī)則:源碼中的依賴(lài)關(guān)系必須只指向同心圓的內(nèi)層,由低層機(jī)制指向高層策略。換句話(huà)說(shuō), 就是任何屬于內(nèi)層圓中的代碼都不應(yīng)該牽涉外層圓中的代碼,尤其是內(nèi)層圓中的代碼不應(yīng)該引用外層圓中代碼所聲明的名字,包括函數(shù)、類(lèi)、變量以及一切其他有命名的軟件實(shí)體。
同樣的道理,外層圓中使用的數(shù)據(jù)格式也不應(yīng)該被內(nèi)層圓中的代碼所使用,尤其是當(dāng)數(shù)據(jù)格式是由外層圓的框架所生成時(shí)??傊?,我們不應(yīng)該讓外層圓中發(fā)生的任何變更影響到內(nèi)層圓的代碼。業(yè)務(wù)實(shí)體
業(yè)務(wù)實(shí)體這一層中封裝的是整個(gè)系統(tǒng)的關(guān)鍵業(yè)務(wù)邏輯, 一個(gè)業(yè)務(wù)實(shí)體既可以是一個(gè)帶有方法的對(duì)象,也可以是一組數(shù)據(jù)結(jié)構(gòu)和函數(shù)的集合。無(wú)論如何,只要它能被系統(tǒng)中的其他不同應(yīng)用復(fù)用就可以。如果我們?cè)趯?xiě)的不是一個(gè)大型系統(tǒng),而是一個(gè)單一應(yīng)用的話(huà),那么我們的業(yè)務(wù)實(shí)體就是該應(yīng)用的業(yè)務(wù)對(duì)象。這些對(duì)象封裝了該應(yīng)用中最通用、最高層的業(yè)務(wù)邏輯,它們應(yīng)該屬于系統(tǒng)中最不容易受外界影響而變動(dòng)的部分。例如,一個(gè)針對(duì)頁(yè)面導(dǎo)航方式或者安全問(wèn)題的修改不應(yīng)該觸及這些對(duì)象, 一個(gè)針對(duì)應(yīng)用在運(yùn)行時(shí)的行為所做的變更也不應(yīng)該影響業(yè)務(wù)實(shí)體。用例
軟件的用例層中通常包含的是特定應(yīng)用場(chǎng)景下的業(yè)務(wù)邏輯,這里面封裝并實(shí)現(xiàn)了整個(gè)系統(tǒng)的所有用例。這些用例引導(dǎo)了數(shù)據(jù)在業(yè)務(wù)實(shí)體之間的流入/流出,并指揮著業(yè)務(wù)實(shí)體利用其中的關(guān)鍵業(yè)務(wù)邏輯來(lái)實(shí)現(xiàn)用例的設(shè)計(jì)目標(biāo)。我們既不希望在這一層所發(fā)生的變更影響業(yè)務(wù)實(shí)體,同時(shí)也不希望這一層受外部因素(譬如數(shù)據(jù)庫(kù)、UI 、常見(jiàn)框架)的影響。用例層應(yīng)該與它們都保持隔離。然而,我們知道應(yīng)用行為的變化會(huì)影響用例本身,因此一定會(huì)影響用例層的碼。因?yàn)槿绻粋€(gè)用例的細(xì)節(jié)發(fā)生了變化,這一層中的某些代碼自然要受到影響。接口適配器
軟件的接口適配器層中通常是一組數(shù)據(jù)轉(zhuǎn)換器,它們負(fù)責(zé)將數(shù)據(jù)從對(duì)用例和業(yè)務(wù)實(shí)體而言最方便操作的格式,轉(zhuǎn)化成外部系統(tǒng)(譬如數(shù)據(jù)庫(kù)以及Web )最方便操作的格式。例如,這一層中應(yīng)該包含整個(gè)GUI MVC 框架。展示器、視圖、控制器都應(yīng)該屬于接口適配器層。而模型部分則應(yīng)該由控制器傳遞給用例,再由用例傳回展示器和視圖。同樣的,這一層的代碼也會(huì)負(fù)責(zé)將數(shù)據(jù)從對(duì)業(yè)務(wù)實(shí)體與用例而言最方便操作的格式,轉(zhuǎn)化為對(duì)所采用的持久性框架(譬如數(shù)據(jù)庫(kù)〉最方便的格式??傊?,在從該層再往內(nèi)的同心圓中, 其代碼就不應(yīng)該依賴(lài)任何數(shù)據(jù)庫(kù)了。譬如說(shuō),如果我們采用的是SQL 數(shù)據(jù)庫(kù),那么所有的SQL 語(yǔ)句都應(yīng)該被限制在這一層的代碼中一一而且是僅限于那些需要操作數(shù)據(jù)庫(kù)的代碼。當(dāng)然,這一層的代碼也會(huì)負(fù)責(zé)將來(lái)自外部服務(wù)的數(shù)據(jù)轉(zhuǎn)換成系統(tǒng)內(nèi)用例與業(yè)務(wù)實(shí)體所需的格式??蚣芘c驅(qū)動(dòng)程序
圖中最外層的模型層一般是由工具、數(shù)據(jù)庫(kù)、Web 框架等組成的。在這一層中,我們通常只需要編寫(xiě)一些與內(nèi)層溝通的勤合性代碼。 框架與驅(qū)動(dòng)程序?qū)又邪怂械膶?shí)現(xiàn)細(xì)節(jié)。Web 是一個(gè)實(shí)現(xiàn)細(xì)節(jié),數(shù)據(jù)庫(kù)也是一個(gè)實(shí)現(xiàn)細(xì)節(jié)。我們將這些細(xì)節(jié)放在最外層,這樣它們就很難影響到其他層了。只有四層嗎圖中所顯示的同心圓只是為了說(shuō)明架構(gòu)的結(jié)構(gòu),真正的架構(gòu)很可能會(huì)超過(guò)四層。并沒(méi)有某個(gè)規(guī)則約定一個(gè)系統(tǒng)的架構(gòu)有且只能有四層。然而,這其中的依賴(lài)關(guān)系原則是不變的。也就是說(shuō),源碼層面的依賴(lài)關(guān)系一定要指向同心圓的內(nèi)側(cè)。層次越往內(nèi),其抽象和策略的層次越高, 同時(shí)軟件的抽象程度就越高其包含的高層策略就越多。最內(nèi)層的圓中包含的是最通用、最高層的策略,最外層的圓包含的是最具體的實(shí)現(xiàn)細(xì)節(jié)??缭竭吔?在圖的右下側(cè),我們示范的是在架構(gòu)中跨邊界的情況。具體來(lái)說(shuō)就是控器、展示器與下一層的用例之間的通信過(guò)程。請(qǐng)注意這里控制流的方向:它從控制器開(kāi)始,穿過(guò)用例,最后執(zhí)行展示器的代碼。但同時(shí)我們也該注意到,源碼中的依賴(lài)方向卻都是向內(nèi)指向用例的。 這里,我們通常采用依賴(lài)反轉(zhuǎn)原則( DI 歸來(lái)解決這種相反性。例如,在Java這一類(lèi)的語(yǔ)言中,可以通過(guò)調(diào)整代碼中的接口和繼承關(guān)系,利用源碼中的依賴(lài)關(guān)系來(lái)限制控制流只能在正確的地方跨越架構(gòu)邊界。假設(shè)某些用例代碼需要調(diào)用展示器,這里一定不能直接調(diào)用,因?yàn)檫@樣做會(huì)違反依賴(lài)關(guān)系原則: 內(nèi)層圓中的代碼不能引用其外層的聲明。我們需要讓業(yè)務(wù)邏輯代碼調(diào)用一個(gè)內(nèi)層接口(圖中的“用例輸出端”〉,并讓展示器來(lái)負(fù)責(zé)實(shí)現(xiàn)這個(gè)接口。我們可以采用這種方式跨越系統(tǒng)中所有的架構(gòu)邊界。利用動(dòng)態(tài)多態(tài)技術(shù),我們將源碼中的依賴(lài)關(guān)系與控制流的方向進(jìn)行反轉(zhuǎn)。不管控制流原本的方向如何,我們 都可以讓它遵守架構(gòu)的依賴(lài)關(guān)系規(guī)則。哪些數(shù)據(jù)會(huì)跨越邊界 一般來(lái)說(shuō),會(huì)跨越邊界的數(shù)據(jù)在數(shù)據(jù)結(jié)構(gòu)上都是很簡(jiǎn)單的。如果可以的話(huà),我們會(huì)盡量采用一些基本的結(jié)構(gòu)體或簡(jiǎn)單的可傳輸數(shù)據(jù)對(duì)象?;蛘咧苯油ㄟ^(guò)函數(shù)調(diào)用的參數(shù)來(lái)傳遞數(shù)據(jù)。另外, 我們也可以將數(shù)據(jù)放入哈希表,或整合成某種對(duì)象。這里最重要的是這個(gè)跨邊界傳輸?shù)膶?duì)象應(yīng)該有一個(gè)獨(dú)立、簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)??傊灰稒C(jī)取巧地直接傳遞業(yè)務(wù)實(shí)體或數(shù)據(jù)庫(kù)記錄對(duì)象。同時(shí),這些傳遞的數(shù)據(jù)結(jié)構(gòu)中 也不應(yīng)該存在違反依賴(lài)規(guī)則的依賴(lài)關(guān)系。例如,很多數(shù)據(jù)庫(kù)框架會(huì)返回一個(gè)便于查詢(xún)的結(jié)果對(duì)象,我們稱(chēng)之為“行結(jié)構(gòu)體”。這個(gè)結(jié)構(gòu)體不應(yīng)該跨邊界向架構(gòu)的內(nèi)層傳遞。因?yàn)檫@等于讓內(nèi)層的代碼引用 外層代碼,違反依賴(lài)規(guī)則。因此,當(dāng)我們進(jìn)行跨邊界傳輸時(shí), 一定要采用內(nèi)層最方便使用的形式。
柚子快報(bào)激活碼778899分享:架構(gòu)簡(jiǎn)潔之道-5.整潔架構(gòu)
精彩文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀(guān)點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。