天天看點

《領域驅動設計:軟體核心複雜性應對之道(修訂版)》—第1章 1.4節知識豐富的設計

本節書摘來自異步社群《領域驅動設計:軟體核心複雜性應對之道(修訂版)》一書中的第1章,第1.4節知識豐富的設計,作者【美】埃裡克•埃文斯(eric evans), 馬利偉 , 萬龍,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

1.4 知識豐富的設計

通過像pcb示例這樣的模型獲得的知識遠遠不隻是“發現名詞”。業務活動和規則如同所涉及的實體一樣,都是領域的核心,任何領域都有各種類别的概念。知識消化所産生的模型能夠反映出對知識的深層了解。在模型發生改變的同時,開發人員對實作進行重構,以便反映出模型的變化,這樣,新知識就被合并到應用程式中了。

當我們的模組化不再局限于尋找實體和值對象時,我們才能充分吸取知識,因為業務規則之間可能會存在不一緻。領域專家在反複研究所有規則、解決規則之間的沖突以及以常識來彌補規則的不足等一系列工作中,往往不會意識到他們的思考過程有多麼複雜。軟體是無法完成這一工作的。正是通過與軟體專家緊密協作來消化知識的過程才使得規則得以澄清和充實,并消除規則之間的沖突以及删除一些無用規則。

示例 提取一個隐藏的概念

我們從一個非常簡單的領域模型開始學習,基于此模型的應用程式用來預訂一艘船在一次航程中要運載的貨物,如圖1-8所示。

《領域驅動設計:軟體核心複雜性應對之道(修訂版)》—第1章 1.4節知識豐富的設計

我們規定這個應用程式的任務是将每件貨物(cargo)與一次航程(voyage)關聯起來,記錄并跟蹤這種關系。現在看來一切都還算簡單。應用程式代碼中可能會有一個像下面這樣的方法:

由于總會有人在最後一刻取消訂單,是以航運業的一般做法是接受比其運載能力多一些的貨物。這稱為“超訂”。有時使用一個簡單的容量百分比來表示,如預訂110%的載貨量。有時則采用複雜的規則——主要客戶或特定種類的貨物優先。

17

這是航運領域的一個基本政策,從事航運業的業務人員都知道它,但在軟體團隊中可能不是所有技術人員都知道這條規則。

需求文檔中包含下面這句話:

允許10%的超訂。

現在,類圖就應該像圖1-9這樣,代碼如下:

《領域驅動設計:軟體核心複雜性應對之道(修訂版)》—第1章 1.4節知識豐富的設計

現在,一條重要的業務規則被隐藏在上面這段方法代碼的一個衛語句②中。第4章将介紹layered architecture,它會幫助我們将超訂規則轉移到領域對象中,但現在我們主要考慮如何把這條規則更清楚地表達出來,并讓項目中的每個人都能了解到它。這将使我們得到一個類似的解決方案。

(1) 如果業務規則如上述代碼所寫,不可能有業務專家會通過閱讀這段代碼來檢驗規則,即使在開發人員的幫助下也無法完成。

(2) 非業務的技術人員很難将需求文本與代碼聯系起來。

如果規則更複雜,情況将更糟。

我們可以改變一下設計來更好地捕獲這個知識。超訂規則是一個政策,如圖1-10所示。政策(policy)其實是strategy模式③[gamma et al. 1995]的别名。我們知道,使用strategy的動機一般是為了替換不同的規則,雖然在這裡并不需要這麼做。但我們要擷取的概念的确符合政策的含義,這在領域驅動設計中是同等重要的動機(參見第12章)。

《領域驅動設計:軟體核心複雜性應對之道(修訂版)》—第1章 1.4節知識豐富的設計

修改後的代碼如下:

新的overbooking policy類包含以下方法:

現在所有人都清楚超訂是一個獨特的政策,而且超訂規則的實作即明确又獨立。

現在,我并不建議将這樣的精細設計應用到領域的每個細節中。第15章将深入闡述如何關注重點以及如何隔離其他問題或使這些問題最小化。這個例子的目的是說明領域模型和相應的設計可用來保護和共享知識。更明确的設計具有以下優點:

19

(1) 為了實作更明确的設計,程式員和其他各位相關人員都必須了解超訂的本質,明白它是一個明确且重要的業務規則,而不隻是一個不起眼的計算。

(2) 程式員可以向業務專家展示技術工件,甚至是代碼,但應該是領域專家(在程式員指導下)可以了解的,以便形成回報閉環。

繼續閱讀