當Subdomain遇見Bounded Context

《實現領域驅動設計》的作者Vernon根據過去幾年DDD的實戰經驗又寫了一本《領域驅動設計精粹》,日前已經在中國翻譯出版。去年底出版社找到我時,讀完英文原著最終還是放棄了翻譯,推薦給了其他同事,並告訴他們出版後準備接受炮火洗禮。

不得不承認Vernon的新書在構建DDD落地體系方面較之上一本有了很大的進步,全書讀起來很連貫,有一定實踐基礎的團隊或個人均可直接上手書中很多的實踐。並且通過一個案例完整敘述了從需求分析開始到最後的團隊迭代開發。當然迭代運作過程中的工作量估計方式,在我看來過於簡單粗暴,雖然強化了架構的最終代碼落地,但卻可能造成一系列的僵化。

本文主要針對Vernon一直以來對Subdomain和Bounded Context的一對一映射關係進行討論。目標是讓更多同學意識到這個方面的不同聲音,從而能夠加深對這兩個概念存在意義的理解,並建立自己的判斷。

區分問題和解決方案是個老大難問題

問題和解決方案總是像一對難以分辨的孿生兄弟,一個人看到的哥哥可能就是另一個人認爲的弟弟。好像程序員在開發Story時,Story成了我們要解決的問題,具體的代碼實現成了解決方案;但當BA在分析同樣一個Story時,問題就成了對應的業務需求,Story只是分析出的解決方案的描述。

當然這個區分有時候可能並沒有那麼重要,Story到底是一個問題,還是一個解決方案,其實我們在迭代過程中並不是很關心。但有時候不做問題和解決方案的區分確是十分危險的,甚至會造成整個產品的失敗。這樣的例子當然是一抓一大把的,比如我經常提及的爲稅務審計人員提供屏幕上多記錄的翻頁功能,就是我職業生涯中記憶最深刻的一次失誤,想當然地採用了“通用”解決方案。

Eric Evan在構建DDD的體系時顯然是思考了問題和解決方案這兩個維度的,我相信這個過程也是十分痛苦的,以至於最後呈現在書裏的實踐並沒有做非常明確地劃分。對於後面的實踐者,包括我們自己,都存在着不一樣的解讀。我們曾經討論過一個DDD實踐的象限劃分,但由於這樣的劃分太過主觀,結果是一組很長的郵件討論。

象限如下圖所示,這是一個如同“PHP是世界上最好語言”般的討論,建議大家慎入,以免上火。

(從問題/解決方案和戰略/戰術 維度分析DDD元模型的元素)

這樣的象限分類確實有點簡單粗暴,但Subdomain和Bounded Context卻是Eric明確定義的兩個核心模型概念。Subdomain是對問題域的分解,而Bounded Context是對解決方案域的分解。這兩個核心概念構建起了DDD處理真實世界複雜度的根基。

建模過程中很多同學其實是忽略Subdomain的,反正目標是Bounded Context。當問題相對簡單時,Subdomain的劃分確實給人感覺是自尋煩惱,劃出Bounded Context後反過來推Subdomain視乎更容易上手。讀《領域驅動設計精粹》時你會發現相似的邏輯,配合書中敏捷項目管理工具的案例(問題也挺簡單)還是挺好用的。

那麼爲什麼我們還要關注Subdomain,還要去區分什麼Core Domain、Support Domain和Generic Domain呢?是否和Story一樣,留給業務和BA就好,程序員還是應該抓緊搞完Bounded Context,然後開寫微服務比較務實呢?

區分Subdomain的必要性

在幫助一個長期合作伙伴構建大規模DDD應用時,我寫了一個“xx階xx步”的體系。也成了很多咱們同事體系性學習DDD的開始。

一年半以後這個團隊組織了所有的技術專家和主管讓我又講了一次這個體系。這次我花了一天時間讓大家體會問題和解決方案的區別,加入了Subdomain的概念。參加團建時,我問了幾個專家和主管他們怎麼看之前的設計,得到更多是務實的“讚賞”。其實我並不在意具體落地時的裁剪,但希望白紙黑字時應該明確原委,這也是我爲什麼拒絕了《領域驅動設計精要》翻譯的原因。

我經常用電商的案例讓大家快速認識到Subdomain劃分的重要性。大浪淘沙之後我們發現淘寶和京東依然是霸主。當年馬爸爸嘲笑強哥構建人肉物流網的寓言也並沒有發生,反而很多人愛上了京東自有物流的速度。當然站在馬爸爸當年對電商問題的認知角度,自建物流是可笑的,畢竟他要解決的核心問題是如何讓琳琅滿目的中小供應商能夠直接對接千千萬萬的用戶,讓用戶能夠更容易的發現適合的商品。

所以從一開始淘寶和京東定義的Core Subdomain就是不一樣的,正是問題認知的區別讓兩家都活了下來,並且活得很好。我們可以看到在線物品展示,吸引消費者方面淘寶一直在引領;而行業裏如果你有機會接觸電商領域,會發現京東物流系統還是蠻厲害的。

這是我們多年後的今天看到的結果呈現,但其實真正決定命運和格局的確是多年前兩家電商對自身核心問題的理解。這個認知驅動出了兩家完全不同的成功電商。

很多同學會說這玩意兒是商業模式,也輪不到我們搞研發的參與。我們拿到的都是既定問題了,再識別Subdomain也沒啥意義了。這個論斷有兩方面問題:

  • 作爲產品和服務的實現者,如果都不參與和關注問題本身的劃分及核心子問題的認知,那麼你很可能在浪費自己的時間,開發出未來被邊緣化,甚至淘汰的系統。這不是危言聳聽,在我的最近諮詢過程中已經鑑證了很多次,比如在這個移動優先的時代去強化PC應用的技術架構。

  • 其次在這個軟件應用空前發展的時代,始終抱着所有模塊都必須是“自研”,所有代碼都必須自己寫的思想,毫無疑問只能成爲“小作坊”。構建現代的複雜系統已經逐步成爲一個生態工程,隨着數字化服務的普及,識別哪些領域應該直接外購使用也成爲了開發團隊的重要能力,構建一個典型的移動應用應該沒有人再會去重頭寫一個二維碼掃描模塊,而是學會從市場上選擇適合的軟件包。

那麼什麼地方應該建,什麼地方應該買,應該如何決定呢?這時候我們會發現Subdomain的劃分就非常有指導意義了。類似二維碼掃描這樣的Generic領域顯然應該是外購的,而當年京東對電商的理解來看物流系統是要自建的。同樣道理還有上次DDD China大會來分享的盒馬生鮮,半年時間已經重寫了三次核心ERP系統。不去思考問題劃分的同學們會覺得盒馬瘋了,ERP在外部看來是多麼成熟的軟件包啊~ 但事實上盒馬生鮮的本質就在如何解決生鮮食品的高效配送上,也可以說是一家特殊的物流公司。

小結一下,即使區分問題和解決方案很抽象,劃分子問題很燒腦,我們還是必須認識到分析問題本身的重要性和必要性。借用雷布斯的成名句“不要用戰術上的勤奮掩蓋戰略上的懶惰”!

Subdomain和Bounded Context的對應關係?

探討了Subdomain的必要性,自然我們需要分析和解決方案這邊Bounded Context分解的關係。第一次看Eric構建的DDD模型腦圖(如下)時,我一直認爲少畫了Subdomain和Bounded Context的對應關係。最早採用DDD時,個人認知是一個Subdomain下應該有多個Bounded Context,即當我們分析出了一個子問題後在針對建模的解決方案進行分解,成爲多個Bounded Context。所以Subdomain:Bounded Context應該是1:N的關係。

(Eric構建的DDD模型腦圖)

然而Vernon一直以來的實踐方式隱含着1:1的對應關係。這樣的對應關係並非沒有道理,如果咱們從一個Bounded Context出發,我們會發現每個Bounded Context必然應該是“解決”部分問題的,而這個部分問題是否就應該是一個Subdomain呢?

當我們拿着這個差異去跟Event Storming的發明者Alberto Brandolini討論時,發現對方委婉地表達了N:N的理解。簡而言之沒有直接的對應關係。當然這種理解隱含了一個Bounded Context是可以服務於多個Subdomain子問題的。比如“產品展示”Bounded Context的模型可能服務於產品銷售和產品評論兩個Subdomain子問題。

這三個對應關係的理解暴露出了大家對問題和解決方案這個老大難問題的糾結~ 當然最簡單的是能夠建立一對一的映射,作爲解決方案高手的程序員們顯然是非常喜歡這個模式的。以至於很多用DDD建模的程序員直接就跳過Subdomain搞起了Bounded Context。當然這也是我堅決反對這樣簡單化映射關係的重要原因。

出於對方法實操性的考慮,我仍然認爲一對多的映射是最優的選擇。誠然在我們的現實世界裏,問題和解決方案是沒有必然對應關係的,他山之石可以攻玉也是古來有之的。但軟件設計本身就是一個問題抽象的過程,這個抽象一定會選取一個視角,也就會放棄部分信息。在這樣的認知下,其實我並不介意在不同子問題的解決方案裏存在一定的重複。

所以,如果讓我來站隊Subdomain和Bounded Context的對應關係,我仍然會選擇一對多。在準確性和易用性之間尋求一個平衡,並保證大家能夠更多的關注問題本身。

堅持持續認知問題

Subdomain和Bounded Context的討論隨着DDD實踐的深入會進一步被大家所討論,不論大家是否能夠共識,這樣的討論都是有好處的。作爲軟件開發的從業者,在面對這個越來越多不確定性的數字化時代,認知問題本身將越來越重要。

Subdomain和Bounded Context在實際認知過程中一定也是相輔相成,逐步清晰的兩個概念。Bounded Context建立一定是針對Subdomain的;而Subdomain的劃分又會通過Bounded Context的模型得到持續地驗證。


文/ThoughtWorks肖然
更多精彩洞見,請關注微信公衆號:思特沃克

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章