2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

領域驅動設計在重構業(yè)務系統(tǒng)中的實踐

 xujin3 2019-05-13

韓宇斌,現(xiàn)就職于羅輯思維得到后端,曾效力于好大夫在線、云智慧等。一線負責過傳統(tǒng)軟件公司ToB類和互聯(lián)網(wǎng)公司ToC類的業(yè)務系統(tǒng),理解體會過其中的相同與不同,擅長利用DDD和OO思想對業(yè)務需求進行分析建模與設計開發(fā)。

張逸老師推薦:倘若說領域驅動設計難,我認為其中的癥結是沒有打通業(yè)務與開發(fā)溝通的橋梁,各自為政,導致開發(fā)對業(yè)務傻傻不了解,業(yè)務對開發(fā)則怨言滿滿。本文來自得到后端開發(fā)工程師的一線經(jīng)歷,通過引入領域驅動設計解決了前期讓人絕望的問題。

編者按:領域建模首先要解決業(yè)務領域問題,而這不是翻譯過來的一個個需求和用例,是需要挖掘背后的專業(yè)領域,以及客戶真實的需求。本文就是很好的一個案例。

學習領域驅動設計(DDD)相關的知識有一段時間了,但是一直苦惱于其中的一些概念無法理解透徹,導致無法落地實現(xiàn)甚至生根發(fā)芽。機緣巧合,不久前的工作內容中,需要把之前分散在若干個業(yè)務系統(tǒng)中(微服務)的購買相關功能進行梳理重構,在這個重構的過程中,充分運用了領域驅動設計中戰(zhàn)略設計部分的思想,達成了目標。

本文將結合一些文字和圖片,圍繞著領域驅動設計中戰(zhàn)略部分的三個核心概念:領域通用語言(UBIQUITOUS LANGUAGE),領域模型(Domain)和限界上下文(Bounded Context),來分享下心得。

1

系統(tǒng)居然不能完全解決業(yè)務的問題

訂單化系統(tǒng)的前世

入職得 到后端不久,團隊交給我一份設計文檔和排期計劃,要求完成個開發(fā)任務,實現(xiàn)一個“訂單化”系統(tǒng)。文檔中,該系統(tǒng)的設計目標是:

實現(xiàn)一個代理服務,對接商城平臺組的訂單系統(tǒng)和基礎平臺組的支付系統(tǒng),然后推動近若干個業(yè)務系統(tǒng)改造,把原來直接調用外部系統(tǒng)的方式,改成調用這個新的代理服務。

讓我們看下文檔中的架構圖,簡潔明了,而我的工作也似乎就是個“體力活”。

如果是剛出道那會,拿到設計文檔,也許我早就不管三七二十一地敲代碼了。但是,經(jīng)歷過多年在業(yè)務開發(fā)線上摸爬滾打,加上對學習OO和領域驅動設計的一些領悟,直覺告訴我沒那么簡單,我應該了解清楚來龍去脈再動手……

經(jīng)過調研,我終于明白了“訂單化”是什么?顧名思義,就是把得到app內所有的虛擬商品在交付時用標準的訂單號關聯(lián)起來?你也許會好奇,一個電商平臺居然沒有訂單?我相信“存在即合理”,當時這么做肯定有當時的原因和背景,說白了一切都是為了快速上線,快速驗證得到app的商業(yè)模式,活下去比設計實現(xiàn)一個完美的系統(tǒng)優(yōu)先級更高。

沒有訂單的購買機制運行了一年多后,商城平臺組實現(xiàn)了訂單系統(tǒng),經(jīng)過財務核算部門的“努力”推動,若干后端業(yè)務方把虛擬商品的購買對接了訂單系統(tǒng)的三個接口(創(chuàng)建、支付、簽收),這就是最初的訂單化的“萌芽”。

如下圖,以精品課系統(tǒng)舉例,要實現(xiàn)精品課的售賣,該系統(tǒng)要和若干個外部系統(tǒng)直接打交道,如果把別的幾個業(yè)務系統(tǒng)的調動關系也畫上,腦補一下這個圖會成為什么樣子。不管怎樣,財務核算部門的第一步要求是實現(xiàn)了,那就是用訂單號串起來了所有的購買信息,實現(xiàn)了原始樸素的“訂單化”要求。

如此復雜的調用關系,和“高內聚低耦合”背道而馳,很快就暴露了問題:業(yè)務方要求在訂單簽收的時候增加一個簽收時間字段,并且要求傳遞寫入已購數(shù)據(jù)表的實際時間。這個很小的需求,據(jù)參與的同事說,投入了20多人/日,將近一個月才上線,因為要同步改數(shù)個業(yè)務系統(tǒng)呢!

團隊嘗到了痛苦,決定改變,于是下決心做一個“訂單化”系統(tǒng),同時把財務要求的數(shù)據(jù)校驗規(guī)則加上。

訂單化系統(tǒng)不能完全解決業(yè)務的問題

分析業(yè)務規(guī)則并讀了一些代碼后,整理出了訂單化系統(tǒng)的一些分析和設計文檔,經(jīng)過了團隊內部確認理解正確,找業(yè)務方在溝通一下就可以開工了。如下圖,是其中在第三方支付(微信和支付寶)這個場景下的時序圖:

開發(fā)工作眼看著就要開始了,我?guī)е莆盏膬热?,滿懷信心的去和合作部門(關注訂單化系統(tǒng)的一些“老板”們)交流,卻感覺大家關注的點甚至方向都常常不一致,越交流內心越分裂。

我作為訂單化系統(tǒng)的負責人是乙方,最關心的是:基于現(xiàn)有確定的需求,如何盡快上線訂單化系統(tǒng)。

而他們甲方關心的是:一定要正確的記賬(面向現(xiàn)在),能夠高效準確的算賬(面向未來),把過去的賬給解釋清楚(面向過去),似乎對“訂單化”系統(tǒng)并不是那么“感興趣”。

我的目標在財務生態(tài)圈里只是個過程!怎么達到真正的目標?我該怎么辦?那個時間段感受到了雙重的壓力,一面來自于業(yè)務方,因為交給我的開發(fā)任務居然不能完全解決業(yè)務的問題,一面來自于開發(fā)團隊內部,領導們不理解為什么訂單化系統(tǒng)遲遲不能取得顯著進展……

轉折點

帶著問題,我參與了財務審計對賬工作。開始時,可以用“身陷重圍,十面埋伏”來形容,因為幾乎每天都會被“拷問”,為什么這么多問題數(shù)據(jù)?誰是對應的產品經(jīng)理呢?得到端誰對權益數(shù)據(jù)準確性負責呢?讓你們老大招個懂財務的產品經(jīng)理吧!誰都能聽出來,是對我能否勝任工作的擔憂和不信任……

終于順利出關,完成了公司的要求,自己直接和業(yè)務方的伙伴們,面對面的工作近一個月,讓我收獲頗豐:

  • 從財務角度,理解了和體會了正確記錄數(shù)據(jù)的重要性

  • 推進已知問題的止損,理解了得到“訂單化”在全局的地位

  • “提煉”了一些“統(tǒng)一語言”

  • 自己下決心:不能為了“訂單化”而實現(xiàn)“訂單化”

  • 收獲了些許財務思維,和財務相關的數(shù)據(jù)變動和規(guī)則結論,要“記在小本本上”

  • 收獲了財務生態(tài)圈的信任。信任很關鍵,一個團隊或者跨團隊協(xié)作時,信任本身就是生產力。

2

“訂單化”系統(tǒng)演變?yōu)榱恕坝唵谓桓丁?系統(tǒng)

領域驅動設計(DDD)思想指導的開發(fā)過程,是一個全程強調“領域模型”的開發(fā)過程,首先開發(fā)團隊要和領域專家去針對業(yè)務需求進行充分的討論溝通,才能確定真正的問題域和業(yè)務期望。

主動與業(yè)務的溝通

下面的圖,是一次找財務方向的產品經(jīng)理溝通討論時給我畫的,產品經(jīng)理說第一次有技術主動和她聊財務相關的業(yè)務,一高興就給我講了很多。

為了讓自己的理解和產品經(jīng)理想要表達的不產生太大的偏差,當天結合這個草圖,趕緊畫了一個自己理解的圖,第二天又去給產品經(jīng)理講了一遍。反述的過程,自己明白訂單化在全局的位置,雖然貌似不起眼但是卻擔負著得到所有虛擬商品的交付。

經(jīng)過和業(yè)務方的多次交流后,我們逐漸提煉和理解了一些“統(tǒng)一語言”,舉例如下:

  • 訂單完整的生命周期:下單,支付,已支付待交付,交付(發(fā)貨),簽收

  • 確收:收入和交付數(shù)據(jù)核對無誤,可以確認為財務收入

  • 權益:用戶購買虛擬商品后,獲得可以學習對應課程的權利

  • 補償:該給權益的時候沒給,要補上權益

回到領域驅動設計,扣一下字眼。首先,一個領域,解決一個核心問題,任何一個系統(tǒng)都會屬于某個特定的領域;確定了系統(tǒng)所屬的領域,相當于確定了系統(tǒng)的核心目標;確定了系統(tǒng)的核心業(yè)務,那么要解決的關鍵問題、問題的范圍邊界就基本確定了。驅動,我理解的是回答優(yōu)先級和孰輕孰重,前面的“訂單化”系統(tǒng)之所以不能解決業(yè)務的問題,就是因為陷入了誤區(qū)之一“還沒有確定自己要干什么,就陷入技術細節(jié)”。

訂單化系統(tǒng)演變?yōu)椤坝唵谓桓断到y(tǒng)”

經(jīng)過繼續(xù)深入調研后,把“訂單化”要完成的內容,劃分成了支付和交付兩部分,如下圖。

重新確定的領域問題是:訂單簽約和履約,正確的交付權益。從全局角度看,就是交易與訂單。交易是行為,訂單是契約,交付是履約。得到后端的角度看,核心領域問題是“訂單交付”,所以一個“訂單交付”系統(tǒng)就呼之欲出了。幾乎在同時,公司也確定了要做一個交易中心的中臺服務,去和若干支付系統(tǒng)對接,我把他們起名為“交易生態(tài)圈”。

下面這個圖,用來說明訂單交付系統(tǒng)和其它系統(tǒng)的關系,在整個得到app中用戶發(fā)生購買行為后,一起確保用戶的購買權益及時交付,一起履約訂單這個合同。

“訂單交付系統(tǒng)”的設計建模

從前面的內容中我們可以看到,“訂單化”系統(tǒng)的設計,依然沒有使得各個業(yè)務系統(tǒng)(諸如精品課、訂閱專欄等)從購買交付的商品售賣場景擺脫出來,導致各個業(yè)務系統(tǒng)各自為戰(zhàn)的重復實現(xiàn)了自己不擅長的商品購買交付邏輯,由于缺乏領域知識敏感度,產生的交付數(shù)據(jù)達不到財務核算的精確要求。

這個其實在領域驅動設計思想中也有理論依據(jù),原有的建模方法陷入了“以用戶為中心”的誤區(qū)。DDD的思想認為,建模不能以用戶為中心作為出發(fā)點,在人機交互系統(tǒng)面前,各個系統(tǒng)的領域模型將變得沒有差別,職責會不明,因為無論什么都可以歸結為“用戶的行為”,以用戶為中心來思考領域模型的思維只是停留在需求的表面,而沒有挖掘出真正的需求的本質。

借助DDD的建模思想指導,進行了重新建模,新模型面對的核心領域模型是“商品”,核心限界上下文是“訂單交付”。

實現(xiàn)后的訂單交付系統(tǒng),使得從下單到交付,業(yè)務系統(tǒng)無需關注,感覺不到訂單的存在。

3

用限界上下文保護領域

確定了領域后,就要保護領域不能隨意被“侵犯”,而保護的依據(jù),就是“限界上下文”。如下圖,Eric Evans 用細胞來形容限界上下文,因為“細胞之所以能夠存在,是因為細胞膜限定了什么在細胞內,什么在細胞外,并且確定了什么物質可以通過細胞膜。”這里,細胞代表上下文,而細胞膜代表了包裹上下文的邊界。

對業(yè)務上下文和限界的理解不足,很容易切換到以用戶為中心去建立領域模型的心流模式。

例如,人去乘坐飛機,要強調出'機場登機流程管理'這個上下文的重要性,不管到機場之前是什么角色,人到了登機這個場景就是乘客,是屬于“登機流程”這個上下文的,要遵守這個場景上下文的業(yè)務規(guī)則和規(guī)范,接受“登機流程”的調度指揮,而不是由著自己“肆意妄為”。

由機場“登機流程上下文”業(yè)務規(guī)則調度,和乘客去主動觸發(fā)登記所需要的動作,完全可以表現(xiàn)為兩種設計,偽代碼如下。

前者

登機流程上下文.排隊(乘客)

登機流程上下文.安檢(乘客)

登機流程上下文.擺渡(乘客,航班)

登機流程上下文.登機(乘客,航班)

后者

乘客.排隊(機場)

乘客.我要安檢(機場)

乘客.我要坐擺渡車(擺渡車)

乘客.我要上飛機(航班)

前者是有序的安全的,不會給機場制造意外,后者機場是不可控的。

在“訂單交付系統(tǒng)”推進的過程中,由于大家立場不同,所以遇到一些來破壞領域的事情也就不足為奇,例如我推進了如下的一些動作來保衛(wèi)領域,其中有些動作已經(jīng)完全超越了一名“開發(fā)人員”的職責范圍。一名技術人員敢于對業(yè)務內容做決策,離不開對領域知識的把握。

4

總結

DDD思想指導的開發(fā)過程,首先是開發(fā)團隊要和領域專家去針對業(yè)務需求進行充分的討論溝通,這一點很重要,業(yè)務線的開發(fā)人員有個不好的習慣:被動接受需求,回頭再來抱怨業(yè)務人員或者產品經(jīng)理沒有表述清楚,人非圣賢孰能無過,合作的就是要互相補位。

在一個DDD的一個討論群里,有一位伙伴問,領域驅動設計的價值到底在什么地方?筆者在公司內做了一次關于領域驅動設計的分享后,同樣有小伙伴問我,學習DDD到底能給工作帶來什么?

有的伙伴說,DDD難是因為它沒有固定的招式!這不是一個好回答的問題,因為如果好回答,也許DDD早就像敏捷思想、OO(面向對象)思想、MVC、微服務那樣火遍大江南北甚至五湖四海了……但是如果你些許認真的學習過領域驅動設計,便會發(fā)現(xiàn),到處都有DDD的思想。

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多