久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

領(lǐng)域驅(qū)動設(shè)計DDD詳解:是什么,、為什么,、怎么做,?

 Baruch 2025-01-03 發(fā)布于四川

      在應(yīng)用架構(gòu)的設(shè)計中,,領(lǐng)域驅(qū)動設(shè)計(Domain Driven DesignDDD)占據(jù)著非常重要的位置,,可以說DDD是應(yīng)用架構(gòu)設(shè)計的核心,。   

         DDD為我們提供了一種架構(gòu)設(shè)計方法,既面向業(yè)務(wù),,又面向技術(shù),,從業(yè)務(wù)需求到領(lǐng)域建模,從領(lǐng)域服務(wù)到技術(shù)轉(zhuǎn)化,,強調(diào)開發(fā)人員與領(lǐng)域?qū)<覅f(xié)同,。DDD是埃里克·埃文斯(Eric Evans)在2003年出版的《領(lǐng)域驅(qū)動設(shè)計:軟件核心復(fù)雜性應(yīng)對之道》(Domain Driven Design: Tackling Complexity in the Heart of Software)一書中提出的具有劃時代意義的重要概念,不過這種領(lǐng)域建模和設(shè)計的思想其實早在20世紀就有很多設(shè)計人員重視起來,。DDD通過統(tǒng)一語言,、領(lǐng)域模型,、領(lǐng)域劃分和服務(wù)劃分等一系列手段來降低軟件復(fù)雜度。

      DDD的核心思想是業(yè)務(wù)與技術(shù)相結(jié)合的一種過程,,既強調(diào)業(yè)務(wù)的理解,,又強調(diào)應(yīng)用領(lǐng)域建模方法的使用。DDD本質(zhì)上是面向?qū)ο蠓治龅臄U展和延伸,,它基于面向?qū)ο蠓治黾夹g(shù)進行了分層規(guī)劃,,同時對其中的核心概念和劃分做了詳細的指引。

DDD的價值

      DDD對應(yīng)用架構(gòu)設(shè)計有非常大的指導(dǎo)作用,,具體如下所示,。

  • 統(tǒng)一語言
          團隊成員會在有界的上下文中有意識地形成統(tǒng)一語言,,便于溝通,,減少分歧,以一種所有干系人都能理解的通用語言為相互交流的工具,,在交流的過程中形成領(lǐng)域概念,,然后將這些概念設(shè)計成領(lǐng)域模型。
  • 業(yè)務(wù)知識沉淀
          DDD不以人為中心,,而以業(yè)務(wù)為中心,,通過承接業(yè)務(wù)架構(gòu)的業(yè)務(wù)流程和業(yè)務(wù)能力,并且通過領(lǐng)域知識進行轉(zhuǎn)化,,進而反哺業(yè)務(wù)架構(gòu)和應(yīng)用架構(gòu),。
  • 邊界清晰的應(yīng)用服務(wù)劃分
          用領(lǐng)域模型劃分邊界來界定哪些需求是合理的,一些需求應(yīng)該在什么地方實現(xiàn),,不斷拉齊團隊成員對需求的認知,,讓設(shè)計更加清晰和規(guī)范,分而治之,,控制規(guī)模,。
  • 關(guān)注點分離
          領(lǐng)域模型與數(shù)據(jù)模型分離,業(yè)務(wù)復(fù)雜度與技術(shù)復(fù)雜度分離,,保持結(jié)構(gòu)清晰,,以應(yīng)對不可預(yù)測性挑戰(zhàn)。
  • 團隊協(xié)同
          業(yè)務(wù)人員和設(shè)計人員共同參與,,這樣有助于創(chuàng)建大家都能理解的通用模型,,并用該模型來溝通業(yè)務(wù)需求、數(shù)據(jù)實體和過程模型,。
  • 模型可擴展
          很好地對業(yè)務(wù)需求進行了到領(lǐng)域服務(wù)的轉(zhuǎn)化,,同時是微服務(wù)及項目落地開發(fā)的紐帶,領(lǐng)域模型是可擴展且易維護的,,也提高了相應(yīng)的可重用性和可測試性,。

      當然DDD也不是萬能的,,在采用DDD之前,我們需要考慮是否真正需要,,思考以下幾個問題可以幫助我們做出判斷,。

  • 是否以數(shù)據(jù)為中心,所有操作都是數(shù)據(jù)庫CRUD,?
  • 業(yè)務(wù)邏輯是否只是少量的業(yè)務(wù)場景和用例,?
  • 應(yīng)用功能是否穩(wěn)定?
  • 是否已經(jīng)對業(yè)務(wù)領(lǐng)域足夠了解,?

      如果以上問題的答案基本都是“”,,說明系統(tǒng)并沒有復(fù)雜的業(yè)務(wù)邏輯,則可以用一般的面向數(shù)據(jù)的架構(gòu)或者事務(wù)腳本等模式,。但如果業(yè)務(wù)邏輯復(fù)雜,、變化頻繁、團隊對該領(lǐng)域還缺乏一定的認知,,需要進行領(lǐng)域模型和服務(wù)的梳理,,那么DDD會幫助我們抽象和解決問題。

DDD的設(shè)計理念

      DDD大體的分析過程中,,其中比較關(guān)鍵的幾個切入點是通用語言,、領(lǐng)域、限界上下文,。

圖片

圖例:DDD分析過程

通用語言(Ubiquitous Language)

      業(yè)務(wù)人員和技術(shù)人員在協(xié)作過程中,,如何講同一種語言?在DDD中用通用語言來解決,。通用語言是理解業(yè)務(wù)需求和梳理領(lǐng)域知識的過程,,也是團隊中各個角色就系統(tǒng)目標、范圍與具體功能達成一致的過程,。通用語言可以定義公共術(shù)語,,減少概念混淆,消除歧義和理解偏差,,提升需求和知識消化的效率,,達到概念和代碼的統(tǒng)一,使得虛擬概念和具體實現(xiàn)一致,。

      通用語言可能由團隊所有相關(guān)角色參加,,如業(yè)務(wù)代表、產(chǎn)品經(jīng)理,、業(yè)務(wù)架構(gòu)師,、技術(shù)架構(gòu)師、開發(fā)人員。同時,,領(lǐng)域?qū)<乙卜浅jP(guān)鍵,,領(lǐng)域?qū)<倚枰獙I(yè)務(wù)領(lǐng)域非常了解,或者能夠跟領(lǐng)域?qū)I(yè)人員學(xué)習(xí)到足夠的領(lǐng)域知識,。

      通用語言建立的過程并不容易,,因為技術(shù)人員和領(lǐng)域?qū)<以跍贤ㄟ^程中存在“天然屏障”:

  • 技術(shù)人員考慮的是類、方法,、算法,、繼承、封裝,、代碼等
  • 領(lǐng)域?qū)<铱紤]的是訂單流程,、庫存狀態(tài)、商品類目等

      因此,,在建立領(lǐng)域知識的時候,,雙方必須交換知識,彼此深度參與,,才可能得出領(lǐng)域模型,。知識的范圍涉及領(lǐng)域模型的各個元素,,如果一方感到困惑,,那么應(yīng)該立刻換一種方式,直到雙方能夠理解一致,。

領(lǐng)域(Domain)

      領(lǐng)域是用于確定范圍和邊界的,,DDD將業(yè)務(wù)上的問題限定歸屬在特定的邊界內(nèi),而這些邊界就可以叫作領(lǐng)域,。為了降低業(yè)務(wù)理解和系統(tǒng)實現(xiàn)的復(fù)雜度,,DDD會將領(lǐng)域進一步劃分為更細粒度,也就是子域,。子域根據(jù)自身的重要程度和功能屬性又可以劃分為三類子域,。

  • 核心域
          決定應(yīng)用和系統(tǒng)核心競爭力,它是決定業(yè)務(wù)是否成功的主要因素,,比如電商系統(tǒng)中關(guān)注的會員,、商品、訂單,、交易,、庫存、營銷等,。
  • 通用域
          沒有太多個性化的訴求,,同時被多個子域使用的通用功能子域是通用域,比如統(tǒng)一的認證和權(quán)限管理系統(tǒng),。
  • 支撐域
          既不包含核心競爭力的功能,,又不包含通用功能的子域,,但該功能子域又是必需的,也就是支撐域,,比如某個特定領(lǐng)域的數(shù)據(jù)字典,。

圖片

圖例:DDD子域結(jié)構(gòu)示例

      領(lǐng)域中的核心是領(lǐng)域模型(Domain Model),領(lǐng)域模型具備自己的屬性行為狀態(tài),,并與現(xiàn)實世界的業(yè)務(wù)對象相映射,,領(lǐng)域模型之間具備明確的職責(zé)劃分,領(lǐng)域?qū)ο笤刂g通過聚合和引用來關(guān)聯(lián)相應(yīng)的業(yè)務(wù)規(guī)則,,同時反映通用語言中的領(lǐng)域知識,。

      領(lǐng)域模型通過提煉領(lǐng)域?qū)ο螅x領(lǐng)域?qū)ο笾g的關(guān)系,、屬性和行為,,屬于DDD的核心產(chǎn)物

限界上下文(Bounded Context)

      領(lǐng)域幫助我們對系統(tǒng)進行拆分,,而限界上下文幫助回答各領(lǐng)域之間的邊界及它們?nèi)绾谓换ァ?/span>

DDD中有一個形象的比喻,,“細胞之所以會存在,是因為細胞膜定義了什么在細胞內(nèi),、什么在細胞外,,并且確定了什么物質(zhì)可以通過細胞膜”。

      這個“細胞膜”就是對限界上下文很形象的舉例,。

再舉個例子,,我們在平時的人際溝通中,為了避免同樣的詞語產(chǎn)生歧義,,我們會把這個詞語帶入語言上下文中去理解其語義,。比如,當談到“蘋果”時,,有的人可能想到平時吃的水果,,而有的人可能想到蘋果手機。
?
[圖片]
圖例:DDD領(lǐng)域與限界上下文

      限界上下文是一個顯式的邊界,,領(lǐng)域模型便存在于這個邊界之內(nèi),,通用語言必須限制在這個限界上下文之中。在微服務(wù)設(shè)計中,,一般一個限界上下文理論上就可以設(shè)計為一個微服務(wù),。限界上下文對應(yīng)用的邊界交互有重要作用,可以幫助我們保持模型的一致性,,避免邊界之外問題的混淆,。這一點很重要,因為在大多數(shù)組織中,某些術(shù)語在不同的業(yè)務(wù)領(lǐng)域或團隊中有不同的含義,。

      在限界上下文中,,通過上下文映射圖(Context Map)確立上下文之間的關(guān)系,通過上下游來表達依賴,,最后形成限界上下文如何在應(yīng)用程序中相互配合的全局視圖,。上下文的交互方法有多種,在實際工作中,,目前使用比較廣的是防腐層和統(tǒng)一協(xié)議,。

  • 已發(fā)布的語言(Published Language)
          兩個上下文使用共同的語言,比如SOA服務(wù)總線定義了一堆XML模型,,或者基于共享的文件或數(shù)據(jù)庫,,上下文可以基于此進行直接交互。
  • 開放主機服務(wù)(Open Host)
          又叫統(tǒng)一協(xié)議,,為上下文之間的服務(wù)定義一套包含標準化數(shù)據(jù)結(jié)構(gòu)在內(nèi)的協(xié)議,,比如基于HTTP風(fēng)格的RESTful接口協(xié)議。
  • 共享內(nèi)核(Shared Kernel)
          兩個上下文使用一個共同的代碼內(nèi)核作為通用語言,,比如兩個工程使用同一個Bean基礎(chǔ)模型庫,。
  • 客戶/供應(yīng)商(Customer/Supplier)
          一個上下文使用另一個上下文的服務(wù),有顯著的上下游依賴關(guān)系,,比如基于RPC的服務(wù)交互方式,。
  • 順從者(Conformist)
          一個上下文使用另一個上下文的服務(wù),但彼此之間的關(guān)系并不緊密,,比如基于消息傳遞機制的交互模式,。
  • 防腐層(Anti-Corruption Layer,ACL)
          使用一層適配層來協(xié)助上下文的交互,,隔離業(yè)務(wù)邏輯,比如在商品子域和采購子域之間提供防腐層,,將商品的變更進行收口,,隔離子域內(nèi)的后端業(yè)務(wù)實現(xiàn)。

      這里先就領(lǐng)域和限界上下文舉一個簡單的例子,,此處舉一個關(guān)于購物車訂單支付下單的例子,。

圖片

圖例:DDD領(lǐng)域與界限上下文示例

      購物車進行在線的支付授權(quán),訂單處理下單過程,,并觸發(fā)支付域的付款結(jié)算,。

      這里我們簡化整個建模的過程,假設(shè)已經(jīng)抽象出購物車域,、支付域,、訂單域(通常購物車域也可以被包含在訂單域內(nèi)),核心的CartPayment,、Order,。

      領(lǐng)域之間通過限界上下文進行交互,因為購物車域和支付域密切相關(guān),,需要等待支付授權(quán),,我們通過ACL進行關(guān)聯(lián);而訂單下單和付款動作相對解耦,,通過領(lǐng)域事件在訂單已下單后,,觸發(fā)支付域的付款動作。

DDD的核心概念

      DDD在構(gòu)建領(lǐng)域模型的過程中,,涉及比較多的概念,。這里著重解讀一下以下幾個。
?
圖片

圖例:DDD的核心概念

實體(Entity)

      實體是一個具有唯一身份標識的對象,,并且可以在相當長的一段時間內(nèi)持續(xù)變化,。

      我們可以對實體進行多次修改,一個實體對象可能和它先前的對象大不相同,,但擁有相同的身份標識,,即依然是同一個實體

      對實體而言,,重要的不是其屬性,,而是其延續(xù)性和身份標識。一般實體的唯一標識有兩種生成方式,。

      應(yīng)用可以自動為實體生成唯一標識,,比如JDK自帶的UUID、數(shù)據(jù)庫的自增序列.
      有時也需要綜合業(yè)務(wù)語義來考慮,,比如通過業(yè)務(wù)屬性,、時間、IP等因素生成.

      另外,,實體具有可變性,,這里需要引出兩個概念:

  • 貧血模型
          貧血模型與Bean或者DO對象類似,一般只有Getter和Setter方法,,只作為保存狀態(tài)或者傳遞狀態(tài),,不包含業(yè)務(wù)邏輯,這種只有數(shù)據(jù)沒有行為的對象不是真正的領(lǐng)域?qū)ο?/span>
  • 充血模型
          DDD中的實體屬于充血模型,,會封裝包含這個實體相關(guān)的所有業(yè)務(wù)邏輯,,它既是多個業(yè)務(wù)屬性的載體,又是操作或行為的載體,。

以訂單(Order)為例,,Order有下單,、發(fā)貨和退單等行為,**而面向數(shù)據(jù)設(shè)計方式是將這些行為放到另一個服務(wù)OrderService中,,而不是Order對象中**,。

值對象(Value Object)

      值對象是只關(guān)心屬性的對象,并且是一個沒有標識符的對象,。

      值對象本質(zhì)上是一個集合,,這個集合中包含若干用于描述目的、具有整體概念和不可修改的屬性,。它可以避免屬性零碎,,使屬性歸類更加清晰,從概念理解上也更加完整,。

      值對象在領(lǐng)域模型中是可以被共享的,,它們應(yīng)該是不可變的,當有其他地方需要用到值對象時,,可以將它的副本作為參數(shù)傳遞,。

      值對象與實體的區(qū)別在于:

  • 值對象一般依附于實體而存在,是實體屬性的一部分
  • 值對象沒有唯一標識,,當任何屬性發(fā)生變化時,,都意味著新的值對象產(chǎn)生。
  • 值對象功能單一,,一般是貧血模型,。

以O(shè)rder為例,訂單下的送貨地址(Address)就是典型的值對象,。Address并不隨著Order的產(chǎn)生而產(chǎn)生,,它相對不變,也不需要單獨標識,。

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

      領(lǐng)域中的一些概念不太適合建模為對象,,它們本質(zhì)上是一些操作、一些動作,,代表領(lǐng)域中一個重要的行為,。這些操作或動作往往涉及多個領(lǐng)域?qū)ο?/span>,并且需要協(xié)調(diào)這些領(lǐng)域?qū)ο?/span>共同完成這個操作或動作,,這就是領(lǐng)域服務(wù)。

      領(lǐng)域服務(wù)有一個重要的功能就是可以避免領(lǐng)域邏輯泄露到應(yīng)用層,。如果沒有領(lǐng)域服務(wù),,那么應(yīng)用層會直接調(diào)用領(lǐng)域?qū)ο笸瓿杀驹擃I(lǐng)域服務(wù)執(zhí)行的操作。

      領(lǐng)域服務(wù)體現(xiàn)的行為一定是不屬于任何實體和值對象的,,但它屬于領(lǐng)域模型的范疇,,同時領(lǐng)域服務(wù)應(yīng)該是無狀態(tài)的,,應(yīng)確保領(lǐng)域服務(wù)和通用語言是一致的

  • 領(lǐng)域服務(wù)是無狀態(tài)
  • 領(lǐng)域?qū)ο笫?/span>有狀態(tài)

      雖然服務(wù)本身也是對象,,但它沒有屬性,,只有行為,因此說它是無狀態(tài)的,。

以訂單發(fā)貨(OrderDelivery)為例,,需要Order和履約兩種實體之間通過一定的業(yè)務(wù)邏輯,確保事務(wù)可以作為領(lǐng)域服務(wù),。

聚合(Aggregate)

      聚合的核心思想是將關(guān)聯(lián)減至最少,,這樣有助于簡化對象之間的遍歷,使用一個抽象來封裝模型中的引用,。

聚合由兩部分組成:

  • 一部分稱為根實體,,是聚合中的特定實體。根實體是聚合中所包含的一個特定實體,,是唯一允許外部對象保持對它的引用的元素,。
  • 另一部分描述一個邊界,定義聚合內(nèi)部有什么,。邊界內(nèi)部的對象之間可以互相引用,。

      除根實體外的其他對象都有本地標識,但這些標識只有在聚合內(nèi)部才需要加以區(qū)分,,因為外部對象除根實體外看不到其他對象,。

      聚合行為被視為一個整體,在每個行為完成時,,必須滿足聚合內(nèi)部所應(yīng)用的固定規(guī)則的要求,,即保證數(shù)據(jù)變化的一致性

      根實體最終檢查固定規(guī)則,,如**刪除操作必須一次刪除聚合邊界之內(nèi)的所有對象**,。

過程中有一些最佳實踐,比如可以設(shè)計一些小的聚合,,通過唯一標識引用其他聚合,,并且在邊界之外考慮最終的一致性。

比如,,訂單域可能有很多實體,,如Order、子訂單,、訂單明細,、地址、物流信息,、支付信息等,,而在我們將它們聚合為訂單域后,,這些實體都聚焦在一起,并由Order這個實體作為聚合根對外交互,。

工廠(Factory)

      當創(chuàng)建一個對象或創(chuàng)建整個聚合時,,如果創(chuàng)建工作很復(fù)雜,或者暴露了過多的內(nèi)部結(jié)構(gòu),,則可以使用工廠來進行封裝,。也就是說,將創(chuàng)建復(fù)雜對象的實例和聚合的職責(zé)轉(zhuǎn)移到一個單獨的對象,,這個對象本身在領(lǐng)域模型中可能沒有職責(zé),,但它也是領(lǐng)域設(shè)計中的一部分

設(shè)計模式中的工廠類和工廠方法與領(lǐng)域模型中的工廠概念是相似的,,其可以幫助我們封裝復(fù)雜的對象創(chuàng)建過程,。

      我們可以把工廠作為一種創(chuàng)建復(fù)雜對象和聚合的實現(xiàn)方式。工廠用來封裝對象創(chuàng)建所必需的知識,,它們對創(chuàng)建聚合很有幫助,。當聚合的根建立時,所有聚合包含的對象將隨之建立,。

資源庫(Repository)

      在DDD中,,資源庫作為對象的提供方,能夠實現(xiàn)對象的持久化,,解耦領(lǐng)域內(nèi)業(yè)務(wù)邏輯與底層持久化,。

      每個聚合類型可以對應(yīng)一個資源庫,過程中需要避免實體和值對象成為單純的充血模型,,我們需要資源庫把ORM框架與領(lǐng)域模型隔離,,以屏蔽數(shù)據(jù)訪問的技術(shù)復(fù)雜度。資源庫可以獲取持久化對象,,使應(yīng)用程序和領(lǐng)域設(shè)計與持久化技術(shù)解耦,,讓我們始終聚焦于模型,并且將所有對象的存儲和訪問操作交給資源庫來完成,。在面向接口和依賴注入機制支持下,,資源庫也容易通過Mock等方式進行測試。

圖片

圖例:DDD中資源庫模式

      工廠和資源庫之間存在一定的關(guān)系,,它們都能幫助我們管理領(lǐng)域?qū)ο蟮纳芷?/span>,。然而,工廠關(guān)注的是對象的創(chuàng)建,,而資源庫關(guān)心的是已經(jīng)存在的對象,。

      當一個新對象被添加到資源庫時,它應(yīng)該是先由工廠創(chuàng)建過的,,再被傳遞到資源庫,,以便更好地保存它。

      另外,,資源庫和數(shù)據(jù)訪問對象(Data Access Object,,DAO)的作用類似,但也有所不同,,資源庫以“領(lǐng)域”為中心,,所描述的是“領(lǐng)域語言”,不涉及數(shù)據(jù)庫實現(xiàn)的細節(jié),;而DAO是比資源庫更低的一層,,其包含如何從數(shù)據(jù)庫中提取數(shù)據(jù)的代碼

領(lǐng)域事件(Domain Event)

      領(lǐng)域事件表示領(lǐng)域中所發(fā)生的重要事件,,在事件發(fā)生后通常會導(dǎo)致進一步的業(yè)務(wù)操作,,或者在系統(tǒng)其他地方引起反應(yīng)

      領(lǐng)域事件非常重要,,我們在系統(tǒng)設(shè)計過程中經(jīng)常需要解耦,,技術(shù)人員一般通過MQ方式進行;架構(gòu)人員可能采用事件驅(qū)動架構(gòu)(Event Driven Architecture,,EDA的方式,。Serverless架構(gòu)中核心的就是基于事件編程,這一切的核心就是對領(lǐng)域事件的設(shè)計,,不過當前大部分系統(tǒng)事件(Event)設(shè)計比較隨性,,從而導(dǎo)致Event濫用和無用情況發(fā)生,而領(lǐng)域事件是對我們很好的指引,。

比如,,在訂單的例子中,在訂單下單后,,會進行**庫存凍結(jié),、支付狀態(tài)更新、物流同步**等,,這些都是對系統(tǒng)事件良好的解耦設(shè)計,。

  • Event命名
  •      Domain Name + 動詞的過去式 + Event,如OrderCreatedEvent,。
  • Event內(nèi)容
          EnrichmentPayload中放Data),,Query-Back(通過回調(diào)拿到更多的Data)。
  • Event管理
          通過MQ等保存所有的Events,,并提供良好的Event查詢和回溯,。
  • Event處理
          事件構(gòu)建和發(fā)布、事件數(shù)據(jù)持久化,、事件總線,、消息中間件,、事件接收和處理等。

小結(jié)

圖片

圖例:DDD核心概念

DDD常用的分析方法

DDD常用的分析方法主要有用例分析法,、四色建模法事件風(fēng)暴法,。

用例分析法

      用例分析是比較通用的領(lǐng)域建模方法,可以在**比較傳統(tǒng)的需求調(diào)研過程中結(jié)合領(lǐng)域模型的設(shè)計思路**進行,,核心是通過業(yè)務(wù)需求,、場景流程等梳理用例,進而規(guī)劃領(lǐng)域模型,。

      用例分析的前提是業(yè)務(wù)架構(gòu)的需求輸入,,其中核心是業(yè)務(wù)能力與業(yè)務(wù)流程

比如電商領(lǐng)域的訂單尋源,、庫存鎖定,、商品價格計算、優(yōu)惠券核銷等業(yè)務(wù)能力,,以及訂單處理,、分單和拆單、逆向退款等業(yè)務(wù)流程,。

      每個用例應(yīng)該面向一個或多個場景,,場景主要說明應(yīng)用是如何和最終用戶互動的,也就是誰可以使用應(yīng)用做什么,,從而獲得一個明確的業(yè)務(wù)目標,。

      編寫用例時要避免使用技術(shù)術(shù)語,應(yīng)該使用最終用戶或者領(lǐng)域?qū)<铱梢岳斫獾恼Z言,,進而我們可以基于用例分析法,,根據(jù)語義來整理用例,然后整理領(lǐng)域模型,,大概步驟如下,。

圖片

圖例:用例分析法過程

  • 收集用例
          從業(yè)務(wù)能力、業(yè)務(wù)流程,、業(yè)務(wù)需求描述中進行提取,,收集相應(yīng)的名詞、動詞,、形容詞,,以及對應(yīng)的業(yè)務(wù)場景。
  • 提取實體
    :從名詞中定位出主要實體,,如商品,、SKU、品類等。
  • 提取屬性
          從形容詞中添加實體屬性,,如顏色,、價格等。
  • 添加關(guān)聯(lián)
          從動詞或形容詞中添加實體和實體之間的關(guān)聯(lián),,如商品“包含”SKU,,賣家“開設(shè)”“多家”店鋪等。
  • 完善模型
          識別出初步模型,,驗證并迭代模型,同時補充用例驗證模型,、業(yè)務(wù)流程驗證模型,。

舉個關(guān)于電商的例子:

假設(shè)有這樣的需求描述:“會員使用代金券兌換了很多促銷的商品?!?/span>

我們先從名詞“會員”“代金券”“商品”中提取實體,,并從形容詞“促銷的”提取商品的屬性,進而將動詞“使用”“兌換”識別成關(guān)聯(lián),,同時結(jié)合行業(yè)知識得知,,代金券屬于優(yōu)惠券的一種,最終得出領(lǐng)域模型,。

圖片

圖例:用例分析模型示例

四色建模法

四色建模法在實踐中也比較常用,,其包括以下幾個核心概念。

  • 時間記錄(Moment-Interval)
          具有可追溯性的記錄運營或管理數(shù)據(jù)的時刻或時段對象(如用粉紅色表示),。
  • 人貨場(Party-Place-Thing Archetype,,PPT)
          代表參與到流程中的參與方、地點,、物(如用綠色表示),。
  • 角色(Role)
          在時間記錄與PPT對象(通常是參與方)之間參與的角色(如用黃色表示)。
  • 描述(Description)
          對PPT對象的一種補充描述(如用藍色表示),。

簡單地說,,四色建模法關(guān)注的是,某個人(Party)的角色(PartyRole)在某個地點(Place)的角色(PlaceRole)用某個東西(Thing)的角色(ThingRole)做了某件事情(Moment-Interval,。

下面以一個課程報名繳費的例子對四色建模法進行說明,。

報名人可以為學(xué)生進行報名,產(chǎn)生對應(yīng)的報名登記記錄和課程表,,進而繳費人進行繳費,,產(chǎn)生繳費記錄。

在這個過程中,,“人”有學(xué)生和課程,,對應(yīng)的“角色”是報名人和繳費人,完成的“時間記錄”是報名登記記錄、課程表及繳費記錄,,再加上一些補充描述,。

圖片

圖例:四色建模法示例

事件風(fēng)暴法

      事件風(fēng)暴又稱事件建模,與頭腦風(fēng)暴類似,,可以快速分析復(fù)雜的業(yè)務(wù)領(lǐng)域,,完成領(lǐng)域建模的目標

      事件風(fēng)暴是事件驅(qū)動設(shè)計的典型代表,,是一種快速,、輕量且未得到充分認可的群體建模技術(shù),它對于加速開發(fā)團隊非常適用,。

      事件風(fēng)暴法關(guān)注以下元素,。

  • 事件
          發(fā)生了什么事情,產(chǎn)生了什么結(jié)果(如用橘黃色表示),。
  • 屬性
          事件的輸入,、輸出,是對時間的細化描述,。
  • 命令
          某個動作的發(fā)起者,,可能是人、外部事件,、定時器等(如用藍色表示),。
  • 領(lǐng)域
          領(lǐng)域的聚合、內(nèi)聚,、低耦合,,聚合內(nèi)部保證數(shù)據(jù)的一致性(如用黃色表示)。

簡單理解就是誰在何時基于什么(輸入)做了什么(命令),,產(chǎn)生了什么(輸出),,影響了什么(事件),最后聚合成了什么(領(lǐng)域),。

事件風(fēng)暴催化并加速整個建模過程,,強調(diào)正確的人(業(yè)務(wù)人員、領(lǐng)域?qū)<?、技術(shù)人員,、架構(gòu)師、測試人員等關(guān)鍵角色都要參與其中),、開放空間(有足夠的空間可以將事件流可視化,,讓人們可以交互討論)、即時貼(至少三種顏色),,關(guān)聯(lián)的人充分討論,,集體決策,,從價值角度來審視業(yè)務(wù)流程的合理性。領(lǐng)域事件容易促使業(yè)務(wù)人員和非業(yè)務(wù)人員達成共識,。

下面通過一個電商的例子說明事件風(fēng)暴的主要過程,。

  1. 首先,我們基于業(yè)務(wù)流程和業(yè)務(wù)流程的輸入,,對事件進行頭腦風(fēng)暴,,主要識別應(yīng)用層面的主要狀態(tài)結(jié)果。比如識別出“商品已創(chuàng)建”,,“庫存已扣減”,,“訂單已支付”等。
  2. 其次,,我們來識別命令,,即什么人做什么事,可以識別出運營人員可以添加商品和編輯庫存,,用戶可以創(chuàng)建訂單,并伴隨著對應(yīng)的事件
  3. 再次,,我們來進行聚合,,即將相關(guān)的實體聚合在一起,可以看到商品,、庫存,、訂單三個領(lǐng)域初步識別,并與相關(guān)的命令和事件結(jié)合在一起
  4. 最后,,我們對這些領(lǐng)域進行邊界劃分,,識別出對應(yīng)的限界上下文

圖片

圖例:事件風(fēng)暴示例

DDD分層架構(gòu)

DDD在具體落地實施的過程中,,強調(diào)四層分層結(jié)構(gòu),,將核心概念進行有效的整合,各層的職能定義如下,。

圖片

圖例:DDD分層架構(gòu)

  • 展示層(Facade Layer)
          負責(zé)與不同用戶和應(yīng)用之間的交互協(xié)議和數(shù)據(jù)格式的轉(zhuǎn)換,,因此它又叫用戶接口層。
  • 應(yīng)用層(Application Layer)
          應(yīng)用層是很薄的一層,,負責(zé)展示層與領(lǐng)域?qū)又g的協(xié)調(diào),,它是與其他系統(tǒng)的應(yīng)用層進行交互的必要渠道,負責(zé)對領(lǐng)域?qū)咏M件進行簡單封裝,,例如事務(wù),、調(diào)用應(yīng)用程序的任務(wù)。應(yīng)用層要盡量簡單,,其服務(wù)及方法一般以用例為對應(yīng)關(guān)系,,通常一個用例對應(yīng)到一個應(yīng)用層的服務(wù)方法,方法中不包含業(yè)務(wù)規(guī)則或者知識,不保留業(yè)務(wù)對象的狀態(tài),,只保留應(yīng)用任務(wù)的進度狀態(tài),,更注重業(yè)務(wù)能力或者業(yè)務(wù)流程的相關(guān)展示。主要通過調(diào)用領(lǐng)域?qū)雍突A(chǔ)設(shè)施層來完成協(xié)調(diào),。
  • 領(lǐng)域?qū)樱―omain Layer)
          領(lǐng)域?qū)邮荄DD的核心,,包含一些核心概念,如領(lǐng)域?qū)嶓w,、值對象,、領(lǐng)域服務(wù)、聚合,,以及它們之間的關(guān)系,。它主要負責(zé)表達業(yè)務(wù)概念、業(yè)務(wù)狀態(tài)信息及業(yè)務(wù)規(guī)則,,具體表現(xiàn)形式是領(lǐng)域模型,。DDD提倡充血模型,即盡量將業(yè)務(wù)邏輯歸屬到領(lǐng)域?qū)ο笊稀?/span>
  • 基礎(chǔ)設(shè)施層(Infrastructure Layer)
          基礎(chǔ)設(shè)施層向其他層提供通用的技術(shù)能力,,為應(yīng)用層傳遞消息(如API網(wǎng)關(guān)等),,為領(lǐng)域?qū)犹峁┏志没瘷C制(如數(shù)據(jù)庫資源、中間件交互等),,屏蔽技術(shù)底座能力(如底層服務(wù)的健康度檢查,、配置參數(shù)等)及其他通用的工具類服務(wù)。

除了比較經(jīng)典的四層分層架構(gòu),,DDD還有一種松散分層架構(gòu),,即端口適配器架構(gòu)。

圖片

圖例:端口適配器架構(gòu)

端口適配器架構(gòu)通過劃分內(nèi)部和外部,,系統(tǒng)由內(nèi)而外圍繞領(lǐng)域模型展開,。領(lǐng)域部分位于最內(nèi)層,應(yīng)用程序包含領(lǐng)域模型和業(yè)務(wù)邏輯,,對于外部而言,,通過各種適配器進行上下文集成,包括數(shù)據(jù)持久化,、第三方數(shù)據(jù)集成,,同時基于依賴注入和Mock機制,適配器完成便捷的替換和模擬,。

不論哪種分層架構(gòu),,都遵循以下幾個通用的DDD分層原則。

  • 無環(huán)依賴原則
          組件的依賴關(guān)系中沒有環(huán)路,,如果出現(xiàn),,則需要打破循環(huán)依賴,。
  • 穩(wěn)定依賴原則
          被依賴者應(yīng)該比依賴者更穩(wěn)定,同時組件的抽象程度應(yīng)該與其穩(wěn)定程度保持一致,。一個穩(wěn)定的組件應(yīng)該是抽象的,,這樣便于擴展。
  • 依賴倒置原則
          高層次的模塊不應(yīng)該依賴低層次的模塊,,它們都應(yīng)該依賴抽象,。抽象不應(yīng)該依賴具體,具體應(yīng)該依賴抽象,。

DDD與周邊概念的關(guān)系

      下面我們來看看DDD與一些周邊概念的關(guān)系,。

DDD與數(shù)據(jù)驅(qū)動設(shè)計的關(guān)系

      DDD給我們帶來的是設(shè)計模式的改變。DDD的設(shè)計模式與傳統(tǒng)的面向數(shù)據(jù)驅(qū)動的開發(fā)模式有明顯的區(qū)別,。

圖片

  • 數(shù)據(jù)驅(qū)動設(shè)計從數(shù)據(jù)出發(fā)
    ,,先梳理E-R圖(實體-聯(lián)系圖),設(shè)計數(shù)據(jù)庫表結(jié)構(gòu),,編寫DAO,,然后實現(xiàn)業(yè)務(wù)邏輯。數(shù)據(jù)驅(qū)動設(shè)計主要采用貧血模型,,業(yè)務(wù)邏輯散落在大量的方法中,,當系統(tǒng)越來越復(fù)雜時,開發(fā)時間將成倍增長,,維護成本很高
  • DDD從領(lǐng)域出發(fā)
    ,,分析領(lǐng)域內(nèi)模型及它們之間的關(guān)系,,并進行領(lǐng)域建模,設(shè)計核心業(yè)務(wù)邏輯,,進而實現(xiàn)技術(shù)細節(jié),。通過DDD,定義領(lǐng)域模型,,從而確定業(yè)務(wù)和應(yīng)用的邊界,,保證業(yè)務(wù)與代碼的一致性

在DDD中,,領(lǐng)域模型和數(shù)據(jù)模型是解耦的,,有時也不是一一對應(yīng)的,因此在應(yīng)用DDD進行設(shè)計時,,一定要擺脫數(shù)據(jù)模型優(yōu)先的束縛,,不要讓領(lǐng)域模型被數(shù)據(jù)模型“綁架”,設(shè)計出合理的領(lǐng)域模型是首要任務(wù),。

DDD與微服務(wù)的關(guān)系

微服務(wù)是技術(shù)層面的分布式技術(shù)架構(gòu)模式,,是技術(shù)實現(xiàn)和部署的范疇,,它提倡將應(yīng)用劃分成更細粒度的服務(wù),服務(wù)之間互相協(xié)調(diào),、互相配合,,為用戶提供最終價值。

      DDD根據(jù)限界上下文設(shè)計出的領(lǐng)域模型和領(lǐng)域服務(wù),,通過微服務(wù)進行落地,,并結(jié)合微服務(wù)及其他分布式技術(shù)(如DevOps、CI/CD,、秒殺,、全鏈路壓測等),加速系統(tǒng)的落地,。一個域服務(wù)可由一個微服務(wù)來實現(xiàn),,也可根據(jù)DDD領(lǐng)域分析拆分為多個微服務(wù),對外集合成統(tǒng)一的域服務(wù),。

DDD與企業(yè)架構(gòu)的關(guān)系

      DDD在企業(yè)架構(gòu)中扮演著重要的角色,。DDD不僅是應(yīng)用架構(gòu)中領(lǐng)域建模重要的設(shè)計方法,同時在企業(yè)架構(gòu)中承接業(yè)務(wù)架構(gòu),,并對技術(shù)架構(gòu)及具體落地時微服務(wù)等技術(shù)實現(xiàn)都有著重要的指導(dǎo)作用,。更重要的是,DDD建立了共同語言,,讓企業(yè)的業(yè)務(wù)人員和技術(shù)人員可以高效地溝通,。同時,有些企業(yè)強調(diào)共享能力中心的設(shè)計和沉淀,,DDD可以作為其模型和服務(wù)建設(shè)方法,,結(jié)合其他架構(gòu)服務(wù)設(shè)計模式及相關(guān)的最佳實踐,助力企業(yè)的架構(gòu)設(shè)計與規(guī)劃,。

DDD與開發(fā)實施的關(guān)系

      DDD帶來了很多好處,,本質(zhì)上是設(shè)計模式的改變,讓領(lǐng)域與數(shù)據(jù)解耦,,從業(yè)務(wù)需求出發(fā),,從領(lǐng)域出發(fā),分析領(lǐng)域內(nèi)模型及它們之間的關(guān)系,,并進行領(lǐng)域建模,,設(shè)計核心業(yè)務(wù)邏輯,進而實現(xiàn)技術(shù)細節(jié),。DDD起到了承前啟后的關(guān)鍵作用,,其不僅將業(yè)務(wù)人員和技術(shù)人員連接起來,還把系統(tǒng)從需求,、設(shè)計,、開發(fā),、部署、運維整個生命周期環(huán)節(jié)有效地串接起來,,DDD更多地從總體和頂層設(shè)計,,從問題域、解決方案域,、業(yè)務(wù)模型角度,,不深度干預(yù)其他環(huán)節(jié)細節(jié),邊界清晰,,關(guān)注點分離,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多