天天看點

危險的DDD聚合根

ddd的核心是聚合。這沒有問題,大家都認同。但關于ddd中的聚合方式,其實我還是有些擔心,下面說說我的想法,希望大家參與讨論。

其實當初第一次看到ddd中關于聚合根部分論述的時候,就感覺有些僵化。ddd中的聚合根的分析設計思路大緻是這樣:1、業務本質邏輯分析;2、确認聚合對象間的組成關系;3、所有的讀寫必須沿着這些固有的路徑進行。

這是一種靜态聚合的設計思路。理論上講,似乎沒有什麼問題。但實際上,人對第一步中的業務邏輯分析就是一個漸進的過程,不是穩定不變的。不是誰都可以成為業務領域專家,就算是業務領域專家也不一定都是對的。在我看來,從時間次元和多使用者場景下看,這種靜态的聚合分析設計方法是根本無法保證領域模型的穩定性。

也許有人不了解,那可以打個比喻:過去幾個孩子可以和爸爸媽媽高高興興地一家人生活在一起,但是孩子們長大後是必然要分家的。其實我隻是在強調,人們對業務過程的認識是有局限性的,誰也無法避免。

ddd本來就是處理複雜業務邏輯設計問題。我看到大家用ddd去分析一些小項目的時候,往往為誰是聚合根而無法達成共識。這說明每個人對業務認識的角度、深度和廣度都不同,自然得出的聚合根也不同。試想,這樣的情況下,領域模型怎麼保持穩定。

更現實的解決方式是怎麼在動态過程中盡可能地保證業務領域模型的穩定性。在我看來:對象之間是平等的,沒有誰高人一等(也就是沒有聚合根);場景(業務)是聚合對象行為的唯一理由;複雜的場景是由簡單場景聚合而成。不管業務如何變化,總有子場景是不變的,這樣就能獲得最大的“維護利潤”(業務不變性)。

作為企業軟體開發而言,最大的挑戰就是業務變化。這一方面來源于業務本身的變化(應用系統應用不斷深入和推廣),另一方面是我們對業務認識不斷深入的過程。不能适應變化的系統隻有死路一條。複雜的業務要求軟體架構必須具備很強的适應能力。如前面所說,這是一個漸進的過程。ddd本身就是為了解決複雜業務的軟體開發問題的。“如何避免颠覆式修改”是最大的挑戰。如果發現找的聚合根是錯誤的,那領域模型還可重用的價值還有多大,這種代價和成本是否能夠承受?

核心觀點:

每個人對業務認識的角度、深度和廣度都不同,得出的聚合根也就會不同;這才有了很多時候我們無法對誰是聚合根以及聚合根的邊界大小達成共識;

我們對業務的認識是一個不斷深入的過程,在這個過程中我們的模型也會相應調整;

從ddd的最後落地實作角度來看,最終出來的是一個個聚合。但是因為聚合不僅僅隻是一個根實體,而是還内聚了一堆子實體和值對象。那它的這種内聚結構對于後期因各種原因而發現原來的聚合是錯誤的時候,此時模型重構的成本和代價會相對于“一個所有entity對象都地位平等的模型”的重構成本會更大,特别是在引入了event sourcing時問題更加凸顯,這點也可見我上篇發表的文章;