主頁 > 軟體設計 > DDD如何設計落地?(庫存,產品賬示例)

DDD如何設計落地?(庫存,產品賬示例)

2021-06-16 20:14:10 軟體設計

一. 背景

本文以預算管控服務建設作為一個DDD設計的例子介紹,目標是是呈現一次DDD設計的程序,為了減少繪圖和描述的作業量,文中會對預算管控業務需求和功能做簡化,請重點關注設計的流程,這是我們想傳達的重點,忽略設計細節的合理性,

另外,對于預算管控服務來講,不一定要用DDD來進行分析設計,基于傳統的資料驅動就完全可以滿足需求,但作為介紹DDD實施程序,預算管控是一個不錯的例子(不需要畫太多的圖),在這里我們不討論什么型別專案合適DDD,可以參考:

大致的共識為復雜度高的業務適合DDD,而復雜度一般體現在:

業務流程長

業務場景多

業務概念多

業務系統干系人多

業務系統需要長期維護且持續有變更

業務背景

需要設計一個適用于本地生活場景的資源預算規劃和管控服務,業務需求上主要包括兩方面的用例:

  1. 品牌發放權益需要有一定的限額,不能無限制的發放,包括品牌、門店、活動、人群、權益等維度

  2. 個人消費者參與活動領取權益有次數的限制,不能無限額領取或使用,包括在活動、品牌、門店、商品等維度

目前各業務線針對以上需求,各自實作了部分能力,整體上看較零碎、不完善、不統一,本次目標是設計一個統一的平臺為各業務方提供基礎能力

二. 戰略設計

2.1 業務梳理

2.1.1 業務定位&目標分析

協同分析階段,需要各干系方共同參與,如,業務運營,業務產品,運營產品,平臺架構,業務系統方的技術等,

目標:聚焦業務需求和平臺定位,確定平臺的能力范圍和服務方式

輸出需求檔案:

  1. 提供一個統一的記賬能力,以平臺的方式為各個系統提供記賬服務,

主要功能:

  • 記賬

  • 銷賬

  • 各維度的查賬

  • 庫存創建

  • 庫存扣減、查詢

  • 庫存縮擴容

細化要求:

  • 作為平臺能為客戶提供邏輯上的資料隔離,即A產品方默認不能訪問B產品方資料,如需要訪問需要經過授權同意

  • 作為平臺需要提供同步記賬能力和異步記賬能力,并提供明確的“能力范圍”承諾

  • 作為平臺需要為產品方提供方案避免重復記賬

  • 除記賬之外,需要提供對應的銷賬能力

  • 需要提供常用的記賬周期(賬期),如時賬,日賬,周賬,月賬,季度賬,年度賬,終身賬,

  • 需要提供自定義記賬周期(賬期)的能力

  • 需要提供一單多賬記賬能力,即一張單據,需要同時記錄日賬和終身賬

  • 需要提供多維度的查賬能力,如按產品方,記賬主體,產品,賬期時間,以及基于這些維度的組合條件查賬

  • 需要提供批量查賬能力,如主體下單一產品的批量賬期時間,主體下的批量產品的單一賬期時間,及其它可能的批量組合

  • 技術上需要保證賬單存盤和記賬動作的事務

  • 技術上需要保證分庫分表的資料存盤均衡性

  • 技術上需要盡量保證分庫分表的資料庫讀寫均衡分布,對可能出現的資料傾斜場景,需要給出明確的說明,和使用限制性規范

  • 能提供性能基準承諾,由測驗團隊對典型場景壓測給出《平臺性能報告》,作為平臺對外服務的一部分

  • 庫存的創建,扣減,查詢,擴容,縮容(縮容量不能少于剩余庫存)

  • 庫存凍結,解凍

  1. 庫存管理

主要功能:

  • 庫存創建

  • 庫存擴容

  • 庫存縮容

  • 庫存扣減

  • 庫存回補

  • 庫存查詢

細化要求:

  • 滿足去UMP的所有要求(去UMP為一個內部專案,各種限定型規則在此不細列)

2.1.2 業務抽象可視化

通過事件風暴或四色建模法來可視化,我們這里選擇事件風暴法,程序主要涉及

  • 識別領域名詞(示意,不包括全部)

  • 識別領域命令(示意,不包括全部)

這里列了主要的命令

  • 場景分析:

主要是識別發出命令的主體是誰,如C端消費者,B端消費者還是某個系統,主要是通個主體在具體Usecase中去串聯命令對于領域物件(對應領域名詞)的影響,串聯業務流程完成領域分析

  • 識別領域事件

在命令發出后對一個領域物件(聚合根)將產生影響,往往對內(聚合根)會生成資料或發生狀態變更;對外(向其他聚合根)發送訊息或觸發事件,

這些事件是業務專家重點關心的結果

這里是先識別領域事件,還是先識別命令可以根據設計者的習慣和熟悉度,自行選擇

最后,整合命令,領域物件和領域事件的關系,得到業務梳理的輸出檔案(實際命令可能比圖中多,如庫存凍結和預扣等):

2.2 統一領域語言(示意,不包括全部)

2.1章中幾個階段是一個來回討論的階段,通常需要經過很多輪的修改和妥協,以至于早期列出的領域名詞、領域事件和命令遠多于上面的圖例,但最后大家需要統一確定其中關鍵的領域名詞、領域事件,并統一領域語言,在后續的討論和設計階段均使用統一語言建模,這里我們用下面的統一語言僅示例產品賬:

術語

描述

記賬主體(principal)(mainPrincipal)(subPrincipal)

記賬主體(id),如,抽獎活動中的消費者記賬,則為cid

賬單(accounting document)(accounting doc)

名詞,一次記賬請求提交的資料為一條記錄,指產品方提交給記賬平臺的原始單據資料

記賬(keep account)

動詞,記錄record的程序

銷賬(write off account)

動詞組,記賬的反向操作

金額(amount)

記賬的數量

賬(account)

按賬期 統計的在該周期內的數額總和相關資料

賬期(account cycle)

賬期(會計周期)的型別,如,日賬,月賬,終身賬等

賬期值(account cycle value)

賬期值,如對于自然日型別的賬期,賬期值可以是“20210415”代表4月15這天的賬

記賬型別(operate type)

操作型別指,記賬或銷賬

2.3 限界上文識別

最后,當領域名詞、領域事件和命令都統一并清理好之后,我們需要圈定合適領域出來,這里要注意,并沒有統一的最佳答案,圈定原則只是遵循現實世界的松緊耦合關系,某些場景下可能有多種選擇,本例較簡單,示例如下

2.4 問題子域識別

在戰略設計階段的最后,按“一個子域負責解決一個獨立業務價值的問題”的原則,將限界背景關系劃分到不同的問題子域(Subdomain)中,同時還需要從更大的域視角來俯覽全域,并按照以下三種型別進行標注:

  • 核心域(Core Domain):是當前產品的核心差異化競爭力,是整個業務的盈利來源和基石,如果核心域不存在,那么整個業務就不能運作,對于核心域,需要投入最優勢的資源(包括能力高的人),和做嚴謹良好的設計,

  • 通用子域(Generic Subdomain):該類問題在界內非常常見,所以很可能有現成的解決方案,通過購買或簡單修改的方式就可以使用,

  • 支撐子域(Supporting Subdomain):該類問題解決的是支撐核心域運作的問題,其重要程度不如核心域,又不屬于通用子域,具備強烈的個性化需求,難以在業內找到現成的解決方案,需要專門的團隊定制開發,

問題子域,是對業務問題的進一步澄清和劃分,同時也是對于資源投入優先級的重要參考,相對限界背景關系來說,問題子域是對業務問題更大粒度的劃分,是在限界背景關系識別后與問題域匹配的一個程序,

通過對于子域進行識別、劃分和型別標注,團隊能夠實作軟體架構在業務邊界上的內聚和解耦,便于逆向應用“康威定律”,

在 DDD 的概念中,限界背景關系和問題子域是兩個不同維度的概念,限界背景關系可能只是真實問題子域的一部分表達,也可能限界背景關系中的一些領域名詞超出實際問題子域的范圍,理論上來說沒有絕對的依賴關系,需要根據實際需求和成本綜合考慮,既要保證便資源分配的合理,又要在降低落地成本的同時保證后期演進的適度兼容,

問題子域識別程序的產出物,如下圖所示:

2.5 限界背景關系映射(示意,不包括全部)

這里只示例產品賬的,明確限界背景關系映射關系,是為了更明確各context之間的關系,在IDDD中給出了9種關系,在本例種只涉及到3種,實際專案中可能比這個復雜的多,尤其是涉及集成和遺留系統的場景,

明確contex之間關系,有助于后續保證系統之間的依賴關系,為后續架構模式的補充模塊做好準備,

三. 戰術設計

3.1領域建模

3.1.1 領域物件提取(聚合/物體識別)

偷個懶,這里只示意產品賬的物體和部分值物件

3.2 業務服務識別

業務服務識別,是為后續系統實作進行的基于業務邊界的模塊拆分分析,常見的拆分方法有:

  • 基于限界背景關系進行拆分:每個限界背景關系為一個服務,優點是每個服務都很小,代碼量少;缺點是拆分粒度太細,導致服務數量過多,增加架構設計的復雜度和運維成本,

  • 基于子域進行拆分:每個子域為一個服務,優點是服務數量相對較少,架構復雜度和運維成本相對更低;缺點是拆分粒度在某些場景下會非常大,導致單個服務變成“小單體”,增加開發成本和代碼分層復雜度,

通過對于業務服務進行劃分,團隊能夠獲得對軟體架構模塊拆分的直接指導,并且還能夠依據“逆康威定律”依據架構結果進行開發團隊的劃分和組建,

下面是預算管控子域的服務拆分示例

子域

服務

預算管控子域

庫存服務

產品賬服務

3.3 業務服務介面識別

單獨對業務服務的介面能力進行識別,是符合面向介面編程原則的,提前定義服務的概要設計方案,可以讓后續團隊成員更快開展作業,也方便后續介面的詳細設計

這里提前識別服務介面,是為了避開技術實作細節的影響,我們在基于具體技術實作的情況下設計介面,通常會干擾領域驅動的設計,我們試想下基于swagger檔案,設計API時,我們是否容易保證API的歸屬正確領域服務,所以提前的概要識別和設定很重要

下面是庫存和賬服務介面識別示例:

子域

聚合根/物體

介面能力

讀寫

賬背景關系

賬單

記賬

賬本

單主體單產品單賬期查賬

單主體批量產品單賬期查賬

庫存背景關系

庫存

創建庫存

扣減庫存

縮擴容庫存

查詢庫存

四. 技術實作

在完成了戰略設計和戰術設計之后,就可以考慮具體的技術詳設,這個階段會設計到具體的架構模式選擇,架構風格和基礎技術,存盤等的選擇,

包括且不限于:

  • 架構風格選擇,單體,soa,微服務,restful,rpc,webservice,ODATA等

  • 架構模式選擇,傳統分層,六邊形,簡潔,洋蔥等

  • 補全組件,如rpc客戶端,mtop,gatway,acl等,這里要分清應用層,,基礎設施和領域

  • 技術框架選型,技術堆疊,服務治理體系

  • API設計,openapi,swagger,blueprint等

  • 領域模型類設計,參考領域模型設計類圖

  • 持久化選擇,這里要考慮哪些需要存盤RDB,哪些用Nosql,哪些只需要記憶體中,在上例產品賬中的賬本就不需要持久化

  • 應用層設計模式選擇,因應用需要,或運營策略需要支持能力要考慮合適的模式支持

  • 考慮其他需求的實作,易測驗性,性能,易維護和運維,安全等

在本例里只示例產品賬的領域模型參考:

其中賬本(accountbook)不需要持久化,其他領域物件均需要持久化

五. 總結

最后需要時刻提醒的,沒到最后實作階段之前應該杜絕提前考慮技術細節和技術實作,否則很容易偏離DDD

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/287911.html

標籤:其他

上一篇:軟體架構設計-軟體架構風格、分層架構

下一篇:簡明入門講義——一文理清負載均衡和反向代理

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more