細(xì)節(jié):內(nèi)部和外部的代碼如何組織?
除了上面提到的原則,我們完全可以自由地按照我們的意愿在每個(gè)區(qū)域內(nèi)組織代碼。
關(guān)于業(yè)務(wù)代碼,內(nèi)部,一個(gè)好主意是選擇根據(jù)業(yè)務(wù)邏輯組織其模塊(或目錄)。
要避免的一個(gè)組織是按類(lèi)型對(duì)類(lèi)進(jìn)行分組。例如“ports”目錄,或“repositories”目錄(如果使用此模式)或“services”目錄。在您的業(yè)務(wù)代碼中考慮100%的業(yè)務(wù),包括組織您的模塊或目錄!理想的情況是能夠打開(kāi)目錄或業(yè)務(wù)邏輯模塊,并立即了解您的程序解決的業(yè)務(wù)問(wèn)題;而不是只看到“存儲(chǔ)庫(kù)”,“服務(wù)”或其他“經(jīng)理”目錄。
另請(qǐng)參閱此主題:
https://medium.com/@msandin/strategies-for-organizing-code-2c9d690b6f33
https://martinfowler.com/bliki/PresentationDomainDataLayering.html
細(xì)節(jié):運(yùn)行時(shí)
您如何實(shí)例化所有這些以滿(mǎn)足運(yùn)行時(shí)依賴(lài)性?如果您使用依賴(lài)注入框架,則可能不需要問(wèn)自己這個(gè)問(wèn)題。但我認(rèn)為要理解六邊形體系結(jié)構(gòu),看看應(yīng)用程序啟動(dòng)時(shí)會(huì)發(fā)生什么是很有趣的。要做到這一點(diǎn),至少在本文的時(shí)候不要使用依賴(lài)注入框架。
例如,如果我們手動(dòng)實(shí)例化一切,我們將如何編寫(xiě)應(yīng)用程序的入口點(diǎn):
class Program
{
static void Main(string[] args)
{
// 1. Instantiate right-side adapter ("go outside the hexagon")
IObtainPoems fileAdapter = new PoetryLibraryFileAdapter(@".\\Peoms.txt");
// 2. Instantiate the hexagon
IRequestVerses poetryReader = new PoetryReader(fileAdapter);
// 3. Instantiate the left-side adapter ("I want ask/to go inside")
var consoleAdapter = new ConsoleAdapter(poetryReader);
System.Console.WriteLine("Here is some...");
consoleAdapter.Ask();
System.Console.WriteLine("Type enter to exit...");
System.Console.ReadLine();
}
}
實(shí)例化順序通常是從右到左:
- 首先我們實(shí)例化Infrastructure端,這里是fileAdapter,它將讀取文件。
- 我們實(shí)例化將由應(yīng)用程序驅(qū)動(dòng)的Domain類(lèi),poetryReader在其中通過(guò)注入將fileAdapter注入構(gòu)造函數(shù)。
- 安裝Application端,consoleAdapter將驅(qū)動(dòng)poetryReader并寫(xiě)入控制臺(tái)。這里poetryReader通過(guò)注入構(gòu)造函數(shù)注入consoleAdapter。
我們說(shuō)內(nèi)部不應(yīng)該依賴(lài)于外部。那么為什么我們將來(lái)自Infrastructure的代碼fileAdapter注入poetryReader,這是來(lái)自Domain的代碼?
我們可以這樣做,因?yàn)橥ㄟ^(guò)查看模式和代碼,除了是PoetryLibraryFileAdapter(基礎(chǔ)結(jié)構(gòu)方面)之外,fileAdapter也是繼承的IObtainPoems實(shí)例。
在實(shí)踐中,PoetryReader不依賴(lài)于PoetryLibraryFileAdapter,而是依賴(lài)于IObtainPoems,它在域中定義良好。您可以通過(guò)查看其構(gòu)造函數(shù)的簽名來(lái)檢查它。
public PoetryReader(IObtainPoems poetryLibrary)
{
this.poetryLibrary = poetryLibrary;
}
PoetryLibraryFileAdapter和PoetryReader是弱耦合的。
細(xì)節(jié):右側(cè)的依賴(lài)性反轉(zhuǎn)
fileAdapter依賴(lài)于業(yè)務(wù)的定義(依賴(lài)于繼承),但在運(yùn)行時(shí)poetryReader可以在實(shí)踐中控制fileAdapter的實(shí)例是依賴(lài)倒置的經(jīng)典案例。
實(shí)際上,如果沒(méi)有IObtainPoems接口,業(yè)務(wù)代碼將依賴(lài)于其定義的基礎(chǔ)結(jié)構(gòu),我們希望避免:
該接口允許反轉(zhuǎn)此依賴(lài)關(guān)系的方向:
除了使業(yè)務(wù)獨(dú)立于外部系統(tǒng)之外,右側(cè)的此接口還允許滿(mǎn)足著名的 SOLID或Dependency Inversion Principle原則。這個(gè)原則說(shuō):
- 高級(jí)模塊不應(yīng)該依賴(lài)于低級(jí)模塊。兩者都必須依賴(lài)于抽象。
- 抽象不應(yīng)該依賴(lài)于細(xì)節(jié)。細(xì)節(jié)必須取決于抽象。
如果我們沒(méi)有接口,我們將擁有一個(gè)依賴(lài)于低級(jí)模塊(Infrastructure)的高級(jí)模塊(Domain)。
注意:對(duì)于左側(cè)和業(yè)務(wù)代碼之間的交互,依賴(lài)性自然是正確的方向。
交互實(shí)現(xiàn)的這種差異與應(yīng)用程序域和域 - 基礎(chǔ)架構(gòu)關(guān)系之間的差異有關(guān)。提醒:應(yīng)用程序端驅(qū)動(dòng)域,而基礎(chǔ)架構(gòu)端由域驅(qū)動(dòng)。
細(xì)節(jié):為什么左邊有接口?
由于A(yíng)pplication和Domain之間的依賴(lài)關(guān)系已經(jīng)在正確的方向上,因此IRequestVerses接口的作用不是反轉(zhuǎn)依賴(lài)關(guān)系。
但是,它仍然有興趣:明確限制應(yīng)用程序代碼和域代碼之間的耦合表面。
實(shí)際上,PoetryReader類(lèi)可以有除IRequestVerses接口之外的其他方法。ConsoleAdapter不了解這一點(diǎn)很重要。
它與另一個(gè)SOLID原則 - 接口隔離原則一致。
客戶(hù)不應(yīng)該被迫依賴(lài)他們不使用的方法。
但是,一旦你理解了意圖,如果左側(cè)的端口只有一個(gè)方法,并且它的實(shí)現(xiàn)只有一個(gè)方法,如我們的例子,接口真的是必要的嗎?在動(dòng)態(tài)語(yǔ)言中,最終將通過(guò)duck typing?
我們可以回答一個(gè)問(wèn)題:您的團(tuán)隊(duì)對(duì)此有何看法?每個(gè)人都清楚隔離目標(biāo),甚至不需要界面來(lái)觸發(fā)對(duì)話(huà)嗎?這取決于你完全決定。
六角形結(jié)構(gòu)測(cè)試
該軟件架構(gòu)的一個(gè)重要優(yōu)點(diǎn)是它有助于測(cè)試自動(dòng)化,這是其原始意圖的一部分。
如何從Application端替換一些代碼?
在一般情況下,左側(cè)代碼的作用可以由測(cè)試框架直接扮演。實(shí)際上,測(cè)試代碼可以直接驅(qū)動(dòng)業(yè)務(wù)邏輯代碼。
注意:該圖說(shuō)明了集成測(cè)試,因?yàn)闆](méi)有替換正確的部分。它也可以替換,見(jiàn)下文。
如何替換基礎(chǔ)設(shè)施方面的一些代碼?
右邊的代碼必須由業(yè)務(wù)驅(qū)動(dòng)。通常,如果要編寫(xiě)單元測(cè)試,可以使用模擬或任何其他形式的測(cè)試雙重替換它,具體取決于您要測(cè)試的內(nèi)容。
達(dá)到了目標(biāo)!
允許應(yīng)用程序由用戶(hù),程序,自動(dòng)化測(cè)試或批處理腳本驅(qū)動(dòng),并與其可能的執(zhí)行系統(tǒng)和數(shù)據(jù)庫(kù)隔離開(kāi)發(fā)和測(cè)試。
小心!這并不妨礙您測(cè)試應(yīng)用程序和基礎(chǔ)結(jié)構(gòu)代碼,任何值得測(cè)試的代碼。在這個(gè)主題上,我再次向您推薦實(shí)踐測(cè)試金字塔系列。
事實(shí)上,通過(guò)組合我們替換或不替換的內(nèi)容,我們可以看到,通過(guò)這種架構(gòu),我們可以測(cè)試我們想要的東西:
- 整個(gè)域單獨(dú),
- 在Infrastructure端獨(dú)立地集成Application和Domain
- 在應(yīng)用程序端獨(dú)立地集成域和基礎(chǔ)結(jié)構(gòu)
-
Web
+關(guān)注
關(guān)注
2文章
1286瀏覽量
71069 -
代碼
+關(guān)注
關(guān)注
30文章
4894瀏覽量
70448
發(fā)布評(píng)論請(qǐng)先 登錄
MC14069UBDR2G六角逆變器的相關(guān)資料推薦
一種改進(jìn)的六角形砍邊細(xì)分方法
自行車(chē)輻條巧制內(nèi)六角扳手

MC14069UBDR2G六角逆變器

外六角和內(nèi)六角螺栓,該如何選擇?
內(nèi)六角螺栓硬度等級(jí)及優(yōu)勢(shì)
六角架構(gòu)學(xué)的三個(gè)原則和技術(shù)1

評(píng)論