反DDD模式之“複用”

老肖想当外语大佬發表於2024-09-21

本文書接上回《反DDD模式之關係型資料庫》,關注公眾號(老肖想當外語大佬)獲取資訊:

  1. 最新文章更新;

  2. DDD框架原始碼(.NET、Java雙平臺);

  3. 加群暢聊,建模分析、技術實現交流;

  4. 影片和直播在B站。

背景

在我們軟體開發過程中,“複用介面(webapi)”、“複用服務(service)”是非常常見的現象,很多老司機都會為自己設計的程式碼可以“複用”而感到有成就感。然而當我們在一個較長的時間週期去看待系統的迭代過程,會發現這些“複用”,往往會成為後來迭代的絆腳石,修改程式碼牽一髮而動全身,細微的修改也會引發廣泛的影響面,從這個角度看,“複用”是不利於系統的可維護性的。

今天我們就來深度探討一下“複用”和DDD之間的關係,開啟一個不同的視角。

複用的本質

下圖展示了一個非常典型的複用例子,不少開發者習慣提供一個“儲存介面”來滿足“建立”和“編輯”場景:

按照我們的慣例,“連線”代表著“耦合”,所以“複用”介面,本質上就是把不同的業務場景耦合在了一起,當一個場景發生變化時,同時會影響到其它場景。

進一步地推導,兩個元素的耦合即打破它們的邊界,它們因為耦合而成為了一個更大的整體:

而DDD的價值觀是保持明確的邊界,打破邊界則與之完全相反,因此可以得出打破邊界即反DDD:

把上面的推導過程整合在一起就是下圖這樣:

去掉中間過程,最終我們得出標題的的結論“複用”是一種“反DDD模式”:

限定條件

另外一方面,“複用”一詞的含義還是比較廣泛的,例如我們有兩個系統,A系統和B系統都呼叫某家的“支付介面”,這算不算複用“支付介面”呢?在我們今天討論的角度看,這不算複用,因為都是“支付場景”呼叫“支付介面”,場景其實是同一個。

那麼我們需要限定一下範圍,這裡探討的複用是指:為不同的場景或者目的所做的複用。基於這個範圍我們可以看到一些典型的複用案例:

  • RestfulAPI複用

  • 後端服務複用

  • 業務中臺複用

而這些場景,我相信很多老司機都有過痛徹心扉的體驗,複用一時爽,迭代火葬場。

不要複用

基於前面推導的認知,我們知道複用作為反DDD模式,並不會為我們帶來價值,反倒會使得系統喪失可維護性,因此我們在實踐DDD過程中總結了一些原則,其中重要的部分就是“不要複用”:

  • 為每個前端場景建立一個API;

  • 為每個API建立各自的輸入輸出實體(RequestDto、ResponseDto);

  • 為每個操作建立各自的命令(Command);

下面貼出DDD原則的文件和截圖:

https://netcorepal.github.io/netcorepal-cloud-framework/rules-of-ddd/rules-of-ddd/

實戰專案

目前開源DDD實戰專案d3shop已經啟動了,你可以自由地參與需求討論、建模設計、程式碼貢獻中來,我們每週都會針對模型設計、程式碼做直播評審和連麥討論,從而幫助你更沉浸地體驗DDD實踐帶來的成長和收益。

專案程式碼:https://github.com/netcorepal/d3shop

相關文章