0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

為什么要用洋蔥架構(gòu)?洋蔥架構(gòu)層是如何構(gòu)成的

jf_ro2CN3Fa ? 來(lái)源:Ritesh Kapoor ? 2023-02-02 11:35 ? 次閱讀

領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(Domain-driven design,DDD)是一種為復(fù)雜需求開發(fā)軟件的方法,它將軟件的實(shí)現(xiàn)與不斷發(fā)展的核心業(yè)務(wù)概念模型緊密地結(jié)合在一起。

領(lǐng)域是一個(gè)知識(shí)的范疇。它指的是我們的軟件所要模擬的業(yè)務(wù)知識(shí)。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的中心是領(lǐng)域模型,它對(duì)一個(gè)領(lǐng)域的流程和規(guī)則有著深刻的理解。洋蔥架構(gòu)實(shí)現(xiàn)了這一概念,并極大地改善了代碼的品質(zhì),降低了復(fù)雜性,并且支持不斷發(fā)展的企業(yè)系統(tǒng)。

fb7daaba-a28a-11ed-bfe3-dac502259ad0.png

為什么要用洋蔥架構(gòu)?

領(lǐng)域?qū)嶓w是核心和中心部分。洋蔥架構(gòu)是建立在一個(gè)領(lǐng)域模型上的,其中各層是通過接口連接的。其背后的思想是,在領(lǐng)域?qū)嶓w和業(yè)務(wù)規(guī)則構(gòu)成架構(gòu)的核心部分時(shí),盡可能將外部依賴性保持在外。

它提供了靈活、可持續(xù)和可移植的架構(gòu)。

各層之間沒有緊密的耦合,并且有關(guān)注點(diǎn)的分離。

由于所有的代碼都依賴于更深的層或者中心,所以提供了更好的可維護(hù)性。

提高了整體代碼的可測(cè)試性,因?yàn)閱卧獪y(cè)試可以為單獨(dú)的層創(chuàng)建,而不會(huì)影響到其他的模塊。

框架/技術(shù)可以很容易地改變而不影響核心領(lǐng)域。例如,RabbitMQ 可以被 ActiveMQ 取代,SQL 可以被 MongoDB 取代。

原則

洋蔥架構(gòu)是由多個(gè)同心層構(gòu)成,它們相互連接,并朝向代表領(lǐng)域的核心。它是基于控制反轉(zhuǎn)(Inversion of Control,IoC)的原則。該架構(gòu)并不關(guān)注底層技術(shù)或框架,而是關(guān)注實(shí)際的領(lǐng)域模型。它是基于以下原則:

依賴性

圓圈代表不同的責(zé)任層。一般來(lái)說,我們潛入得越深,就越接近于領(lǐng)域和業(yè)務(wù)規(guī)則。外圈代表機(jī)制,內(nèi)圈代表核心領(lǐng)域邏輯。外層依賴于內(nèi)層,而內(nèi)層則對(duì)外圈一無(wú)所知。通常情況下,屬于外圈的類、方法、變量和源代碼依賴于內(nèi)圈,但是反過來(lái)也一樣。

數(shù)據(jù)格式/結(jié)構(gòu)可能因?qū)佣悺M鈱拥臄?shù)據(jù)格式不應(yīng)該被內(nèi)層使用。例如,API 中使用的數(shù)據(jù)格式可以與 DB 中用于持久化的數(shù)據(jù)格式不同。數(shù)據(jù)流可以使用數(shù)據(jù)傳輸對(duì)象。每當(dāng)數(shù)據(jù)跨層/跨界時(shí),它應(yīng)該以方便該層的形式出現(xiàn)。例如,API 可以有 DTO,DB 層可以有 Entity Objects,這取決于存儲(chǔ)在數(shù)據(jù)庫(kù)中的對(duì)象與領(lǐng)域模型的不同。

數(shù)據(jù)封裝

每個(gè)層/圈封裝或隱藏內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),并向外層公開接口。所有的層也需要提供便于內(nèi)層消費(fèi)的信息。其目的是最小化層與層之間的耦合,最大化跨層垂直切面內(nèi)的耦合 。我們?cè)谳^深的層定義抽象接口,并在最外層提供其具體實(shí)現(xiàn)。這樣可以確保我們專注于領(lǐng)域模型,而不必過多地?fù)?dān)心實(shí)現(xiàn)細(xì)節(jié)。我們還可以使用依賴性注入框架,比如 Spring,在運(yùn)行時(shí)將接口與實(shí)現(xiàn)連接起來(lái)。例如,領(lǐng)域中使用的存儲(chǔ)庫(kù)和應(yīng)用服務(wù)中使用的外部服務(wù)在基礎(chǔ)設(shè)施層實(shí)現(xiàn)。

fba2b530-a28a-11ed-bfe3-dac502259ad0.png

洋蔥架構(gòu)中的數(shù)據(jù)封裝

關(guān)注點(diǎn)的分離

應(yīng)用被分為若干層,每一層都有一組職責(zé),并解決不同的關(guān)注點(diǎn)。每一層都作為應(yīng)用中的模塊/包/命名空間。

耦合性

低耦合性,可以使一個(gè)模塊與另一個(gè)模塊交互,而不需要關(guān)注另一個(gè)模塊的內(nèi)部。所有的內(nèi)部層都不需要關(guān)注外部層的內(nèi)部實(shí)現(xiàn)。

洋蔥架構(gòu)層

讓我們通過一個(gè)創(chuàng)建訂單的用例來(lái)了解架構(gòu)的不同層和它們的職責(zé)。當(dāng)收到一個(gè)創(chuàng)建訂單的請(qǐng)求時(shí),我們會(huì)對(duì)這個(gè)訂單進(jìn)行驗(yàn)證,將這個(gè)訂單保存在數(shù)據(jù)庫(kù)中,更新所有訂單項(xiàng)目的庫(kù)存,借記訂單金額,最后向客戶發(fā)送訂單完成的通知。

fbb8d5fe-a28a-11ed-bfe3-dac502259ad0.png

說明各層之間的依賴關(guān)系的包圖

fbdb2b54-a28a-11ed-bfe3-dac502259ad0.png

領(lǐng)域模型/實(shí)體

領(lǐng)域?qū)嶓w是領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的基本構(gòu)件,它們被用來(lái)在代碼中為通用語(yǔ)言的概念建模。實(shí)體是在問題域中具有唯一身份的領(lǐng)域概念。領(lǐng)域?qū)嶓w封裝了屬性和實(shí)體行為。它應(yīng)該是獨(dú)立于數(shù)據(jù)庫(kù)或網(wǎng)絡(luò) API 等特定技術(shù)的。例如,在訂單領(lǐng)域,訂單是一個(gè)實(shí)體,并具有像 OrderId、Address、UserInfo、OrderItems、PricingInfo 這樣的屬性以及像 AddOrderItems、GetPricingInfo、ValidateOrder 這樣的行為。

fbeaa386-a28a-11ed-bfe3-dac502259ad0.png

訂單實(shí)體類

領(lǐng)域服務(wù)

領(lǐng)域服務(wù)負(fù)責(zé)保持領(lǐng)域邏輯和業(yè)務(wù)規(guī)則。所有的業(yè)務(wù)邏輯應(yīng)該作為領(lǐng)域服務(wù)的一部分來(lái)實(shí)現(xiàn)。領(lǐng)域服務(wù)由應(yīng)用服務(wù)協(xié)調(diào),以服務(wù)于業(yè)務(wù)用例。它們不是典型的 CRUD 服務(wù),通常是獨(dú)立的服務(wù)。領(lǐng)域服務(wù)負(fù)責(zé)復(fù)雜的業(yè)務(wù)規(guī)則,如在處理訂單時(shí)計(jì)算價(jià)格和稅收信息,保存和更新訂單的訂單庫(kù)接口,更新購(gòu)買物品信息的庫(kù)存接口等。

它包含了對(duì)其目標(biāo)非常關(guān)鍵的算法,并且將用例作為應(yīng)用的核心來(lái)實(shí)現(xiàn)。

應(yīng)用服務(wù)

應(yīng)用服務(wù)也被稱為“用例”,是只負(fù)責(zé)協(xié)調(diào)請(qǐng)求步驟的服務(wù),不應(yīng)該有任何業(yè)務(wù)邏輯。應(yīng)用服務(wù)與其他服務(wù)交互,以滿足客戶的請(qǐng)求。讓我們考慮一下用例,用一個(gè)物品清單創(chuàng)建一個(gè)訂單。我們首先需要計(jì)算價(jià)格,包括稅收計(jì)算/折扣等,保存訂單項(xiàng)目并向客戶發(fā)送訂單確認(rèn)通知。定價(jià)計(jì)算應(yīng)該是領(lǐng)域服務(wù)的一部分,但涉及定價(jià)計(jì)算、檢查可用性、保存訂單和通知用戶的協(xié)調(diào)工作應(yīng)該是應(yīng)用服務(wù)的一部分。應(yīng)用服務(wù)只能由基礎(chǔ)設(shè)施服務(wù)調(diào)用。

基礎(chǔ)設(shè)施服務(wù)

基礎(chǔ)設(shè)施服務(wù)也被稱為基礎(chǔ)設(shè)施適配器,是洋蔥架構(gòu)的最外層。這些服務(wù)負(fù)責(zé)與外部世界交互,不解決任何領(lǐng)域的問題。這些服務(wù)只是與外部資源通信,沒有任何邏輯。例如:外部通知服務(wù)、GRPC 服務(wù)器端點(diǎn)、Kafka 事件流適配器、數(shù)據(jù)庫(kù)適配器。

可觀察性服務(wù)

可觀察性服務(wù)負(fù)責(zé)監(jiān)控應(yīng)用。這些服務(wù)有助于執(zhí)行以下任務(wù):

數(shù)據(jù)收集(指標(biāo)、日志、痕跡):主要使用庫(kù)/側(cè)線來(lái)收集代碼執(zhí)行期間的各種數(shù)據(jù)。

數(shù)據(jù)存儲(chǔ):使用能夠集中存儲(chǔ)所收集的數(shù)據(jù)的工具(分類、索引等)。

可視化:使用允許你對(duì)收集的數(shù)據(jù)進(jìn)行可視化的工具。

一些例子包括 Splunk、ELK、Grafana、Graphite、Datadog。

測(cè)試策略

洋蔥架構(gòu)的不同層有不同的職責(zé),相應(yīng)地也有不同的測(cè)試策略。測(cè)試金字塔是一個(gè)很好的框架,它規(guī)定了不同類型的測(cè)試。屬于領(lǐng)域模型、領(lǐng)域服務(wù)和應(yīng)用服務(wù)的業(yè)務(wù)規(guī)則應(yīng)通過單元測(cè)試進(jìn)行測(cè)試。當(dāng)我們移動(dòng)到外層時(shí),在基礎(chǔ)設(shè)施服務(wù)中進(jìn)行集成測(cè)試更有意義。對(duì)于我們的應(yīng)用,端到端測(cè)試和 BDD 是最合適的測(cè)試策略。

fbfb703a-a28a-11ed-bfe3-dac502259ad0.png

針對(duì)不同層的測(cè)試策略

微服務(wù)

當(dāng)孤立地看待每個(gè)微服務(wù)時(shí),洋蔥架構(gòu)也適用于微服務(wù)。每個(gè)微服務(wù)都有自己的模型、自己的用例,并定義了自己的外部接口,用于檢索或修改數(shù)據(jù)。這些接口可以用一個(gè)適配器來(lái)實(shí)現(xiàn),該適配器通過公開 HTTP Rest、GRPC、Thrift Endpoints 等連接到另一個(gè)微服務(wù)。它很適合微服務(wù),在微服務(wù)中,數(shù)據(jù)訪問層不僅包括數(shù)據(jù)庫(kù),還包括例如一個(gè) http 客戶端,以從另一個(gè)微服務(wù),甚至從外部系統(tǒng)獲取數(shù)據(jù)。

應(yīng)用結(jié)構(gòu)和層數(shù)

fc0bb0e4-a28a-11ed-bfe3-dac502259ad0.pngfc27fa6a-a28a-11ed-bfe3-dac502259ad0.png

應(yīng)用結(jié)構(gòu)和層,包括層如何映射到模塊以及它們之間的依賴關(guān)系。它還描述了對(duì)不同層使用什么樣的測(cè)試策略

模塊化與打包

有兩種方法來(lái)組織應(yīng)用的源代碼:

要么,我們可以將所有的包放在一個(gè)模塊/項(xiàng)目中,要么將應(yīng)用分為不同的模塊/項(xiàng)目,每個(gè)模塊/項(xiàng)目負(fù)責(zé)洋蔥架構(gòu)中的一個(gè)層。

這在很大程度上取決于應(yīng)用的復(fù)雜性和項(xiàng)目的規(guī)模,將源代碼分為多個(gè)模塊。在微服務(wù)架構(gòu)中,模塊化可能有意義,也可能沒有意義,這取決于復(fù)雜性和用例。

框架、客戶端和驅(qū)動(dòng)

基礎(chǔ)設(shè)施層由網(wǎng)絡(luò)或服務(wù)器的框架、數(shù)據(jù)庫(kù)的客戶端、隊(duì)列或外部服務(wù)組成。它負(fù)責(zé)配置和縫合所有的外部服務(wù)和框架。洋蔥架構(gòu)提供了解耦功能,因此在任何時(shí)候交換技術(shù)都會(huì)變得更容易。

我們需要每個(gè)層嗎?

將我們的應(yīng)用分層組織有助于實(shí)現(xiàn)關(guān)注點(diǎn)的分離。但我們需要所有的層嗎?也許需要,也許不需要。這取決于用例和應(yīng)用的復(fù)雜性。根據(jù)應(yīng)用的需要,也可以創(chuàng)建更多的抽象層。例如,對(duì)于沒有很多業(yè)務(wù)邏輯的小型應(yīng)用,擁有領(lǐng)域服務(wù)可能沒有意義。無(wú)論哪一層,依賴關(guān)系都應(yīng)該是從外層到內(nèi)層。

總結(jié)

洋蔥架構(gòu)在開始時(shí)可能似乎有些困難,但是在業(yè)界已經(jīng)得到了普遍的認(rèn)可。這是一種讓軟件易于演進(jìn)的強(qiáng)有力架構(gòu)。通過把應(yīng)用劃分為幾層,可以使系統(tǒng)更加易于測(cè)試、維護(hù)和移植。它有助于在舊框架過時(shí)時(shí)輕松采用新框架/技術(shù)。與其他架構(gòu)風(fēng)格類似,如六邊形、分層、簡(jiǎn)潔的架構(gòu)等,它為常見問題提供了一個(gè)解決方案。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 適配器
    +關(guān)注

    關(guān)注

    8

    文章

    1956

    瀏覽量

    68045
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    764

    瀏覽量

    44157
  • RBAC
    +關(guān)注

    關(guān)注

    0

    文章

    44

    瀏覽量

    9973
  • mongodb
    +關(guān)注

    關(guān)注

    0

    文章

    22

    瀏覽量

    370

原文標(biāo)題:詳解DDD“洋蔥架構(gòu)”

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    討論關(guān)于 單片機(jī)剝洋蔥皮 的編程思想

    有沒有那個(gè)工程師可以講講在單片機(jī)編程中怎么樣使用剝洋蔥皮的思想,謝謝!
    發(fā)表于 09-19 21:59

    正在建立Onion洋蔥中國(guó)站,大家有什么好的建議?

    剛剛簽約代理了加拿大Onion的產(chǎn)品,現(xiàn)在正在著手建立Onion洋蔥中國(guó)站;想著,首先搞個(gè)網(wǎng)站,做個(gè)鏡像,然后慢慢做翻譯工作;然后貼吧,QQ群,微信群……搞創(chuàng)新設(shè)計(jì)大賽……小弟實(shí)在是才疏學(xué)淺,沒有更多有效的辦法,現(xiàn)誠(chéng)信討教,各位大神,有什么好的建議,采納有謝!
    發(fā)表于 05-08 17:13

    談?wù)勅绾卧O(shè)計(jì)MCU程序3架構(gòu)

    程序員們都知道軟件架構(gòu)對(duì)軟件的重要性,那么對(duì)于MCU的程序員來(lái)說該如何架構(gòu)一個(gè)適合MCU的程序呢?MCU的程序架構(gòu)有不少,比如常見的MVC架構(gòu)、三
    發(fā)表于 11-05 11:16

    基于ATCA的測(cè)試系統(tǒng)架構(gòu)是如何構(gòu)成的?

    ATCA在測(cè)試領(lǐng)域有哪些應(yīng)用實(shí)例?基于ATCA的測(cè)試系統(tǒng)架構(gòu)是如何構(gòu)成的?
    發(fā)表于 05-11 07:01

    基于docker技術(shù)的工業(yè)App架構(gòu)是如何構(gòu)成

    基于docker技術(shù)的工業(yè)App架構(gòu)是如何構(gòu)成的?
    發(fā)表于 09-28 06:35

    STM32芯片的架構(gòu)是如何構(gòu)成

    STM32是什么?有哪幾種分類?STM32芯片的架構(gòu)是如何構(gòu)成的?
    發(fā)表于 10-29 07:53

    基于CMSIS標(biāo)準(zhǔn)的軟件架構(gòu)是怎樣構(gòu)成

    CMSIS標(biāo)準(zhǔn)是什么意思?基于CMSIS標(biāo)準(zhǔn)的軟件架構(gòu)是怎樣構(gòu)成的?
    發(fā)表于 11-04 06:06

    CMSIS軟件架構(gòu)概述?

    目錄CMSIS軟件架構(gòu)庫(kù)文件說明CMSIS軟件架構(gòu)CMSIS概述? ? ?CMSIS軟件架構(gòu)由四:用戶應(yīng)用、操作系統(tǒng)及中間件接口
    發(fā)表于 12-22 07:34

    淺談三架構(gòu)原理

    淺談三架構(gòu)原理
    發(fā)表于 01-16 09:14

    架構(gòu)的原理及作用_三架構(gòu)怎么用

    在軟件系統(tǒng)設(shè)計(jì)中,分層式結(jié)構(gòu)是常見的,也是重要的一種結(jié)構(gòu)。三架構(gòu)就是將整個(gè)業(yè)務(wù)應(yīng)用劃分為:界面層、業(yè)務(wù)邏輯、數(shù)據(jù)訪問。每一都職責(zé)明確
    發(fā)表于 12-27 16:19 ?1.7w次閱讀
    三<b class='flag-5'>層</b><b class='flag-5'>架構(gòu)</b>的原理及作用_三<b class='flag-5'>層</b><b class='flag-5'>架構(gòu)</b>怎么用

    沒有人能夠拒絕洋蔥的魅力 realme X大師版 洋蔥6月27日正式開售

    2019年6月27日10點(diǎn),由realme與全球頂級(jí)工業(yè)設(shè)計(jì)大師深澤直人攜手打造的realme X大師版 洋蔥已在京東、天貓、蘇寧易購(gòu)和realme官網(wǎng)準(zhǔn)點(diǎn)開售,售價(jià)為1899元(8GB+128GB
    發(fā)表于 06-28 07:48 ?491次閱讀

    realme X大師版 洋蔥已正式開售

    realme X大師版 洋蔥已在京東、天貓、蘇寧易購(gòu)及realme官網(wǎng)正式開售,realme X大師版 白蒜也將很快與消費(fèi)者見面。
    的頭像 發(fā)表于 07-10 15:05 ?3043次閱讀

    談?wù)労蠖?b class='flag-5'>架構(gòu)的演進(jìn)過程:N-Layered和DDD架構(gòu)介紹

    在本文中,我們討論了 N-layered、DDD、六邊形、洋蔥和清潔架構(gòu)。這些只是眾多存在的架構(gòu)中的一部分,是一些比較出名的架構(gòu)。你可能還聽說過 BCE、DCI 等。
    發(fā)表于 08-16 10:08 ?638次閱讀
    談?wù)労蠖?b class='flag-5'>架構(gòu)</b>的演進(jìn)過程:N-Layered和DDD<b class='flag-5'>架構(gòu)</b>介紹

    javaweb三架構(gòu)和mvc架構(gòu)

    JavaWeb三架構(gòu)和MVC架構(gòu)是當(dāng)前Web開發(fā)領(lǐng)域中常用的兩種架構(gòu)模式。 一、JavaWeb三架構(gòu)
    的頭像 發(fā)表于 11-22 16:41 ?1758次閱讀

    架構(gòu)與設(shè)計(jì) 常見微服務(wù)分層架構(gòu)的區(qū)別和落地實(shí)踐

    前言 從強(qiáng)調(diào)內(nèi)外隔離的六邊形架構(gòu),逐漸發(fā)展衍生出的層層遞進(jìn)、注重領(lǐng)域模型的洋蔥架構(gòu),再到和DDD完美契合的整潔架構(gòu)。架構(gòu)風(fēng)格的不斷演進(jìn),其實(shí)
    的頭像 發(fā)表于 10-22 15:34 ?248次閱讀
    <b class='flag-5'>架構(gòu)</b>與設(shè)計(jì) 常見微服務(wù)分層<b class='flag-5'>架構(gòu)</b>的區(qū)別和落地實(shí)踐