第 9 / 13 部 待錄

分析模式設計模式與重構

《Domain-Driven Design 領域驅動設計》Podcast 準備稿:分析模式、設計模式與重構

書名: 領域驅動設計 Domain-Driven Design(Tackling Complexity in the Heart of Software) 作者: Eric Evans 系列: 啃一本大書(恩普拉氏) 公開標題建議: 啃一本大書|Domain-Driven Design.站在前人肩膀上建模 (9/13) 涵蓋範圍: Part III 第11章 運用分析模式(Applying Analysis Patterns)+ 第12章 將設計模式關聯到模型(Relating Design Patterns to the Model)+ 第13章 重構邁向深層理解(總結)

背景速覽

Part III 收尾集,把三章合在一起。第11章講怎麼用 Fowler 的分析模式(Analysis Patterns)站在前人肩膀上、加速建模;第12章講怎麼把 GoF 的設計模式(Strategy、Composite)用在領域層,但要加一層「領域意義」;第13章是整個 Part III 的總結,把突破、隱含概念、柔性設計、模式運用全部彙整成一幅「重構邁向深層理解」的完整圖景。這集是「程式碼設計三本(DDD+設計模式+重構)怎麼搭」這個主題最直接的對應章節。

一句話重點

別每次都從零開始建模——分析模式(Fowler)提供現成的「模型片段」當起點、設計模式(GoF)提供經過驗證的結構,但用在領域層時,模式必須契合領域概念、加上一層領域意義,而不只是技術解法;而把這一切串起來的引擎,是永不止歇的「重構邁向深層理解」。

值得討論的重點

1. 分析模式:可汲取的知識,不是現成答案

Fowler 的 Analysis Patterns 是「商業建模中常見構造的概念群組」。Evans 用一個會計系統的例子示範:開發者去讀 Fowler《Analysis Patterns》第六章「Inventory and Accounting」,學到 Account、Entry、Transaction、複式簿記等模型片段,拿回來跟同事和領域專家一起改造。過程中發現 Transaction 模式不完全合用(它講不同 Account 間移錢,但這裡是同 Account 內兩筆平衡 Entry),於是保留 Account/Entry、丟掉 Transaction,再結合專家提的 Accrual 概念。

關鍵態度:分析模式是起點而非終點——它給你「調查中的線索、乾淨抽象的詞彙、實作後果的指引」,全都注入消化知識和重構的循環。結果往往「類似但適應了具體情境」,有時甚至看不出明顯關聯,卻是受其啟發。重點警告:用知名分析模式的術語時,要保持它的基本概念完整,因為這既能避坑、又能增強統一語言。

2. 設計模式用在領域層:要加一層領域動機

第12章的核心區別:GoF 設計模式原本是技術焦點,但用在領域層時,首要關注的不是技術便利,而是「它真的契合領域概念嗎」。Evans 拿兩個模式示範:

  • Strategy(又名 Policy):把流程中「變化的部分」抽成獨立的 strategy 物件。Route-Finding 例子——把「找最快 vs 找最便宜」的條件判斷從 Routing Service 裡抽出來,做成可傳入的 Leg Magnitude Policy。當 Strategy 對應到實際的商業策略/政策時,它就不只是實作技巧,而有了領域表達力。
  • Composite:物件由同類的部分組成(樹狀的部分-整體)。Route 由 Route 組成的例子——開發者原本以為 route 是一串無差別的 leg,但專家認為是五個邏輯段落,模型一度變複雜;用 Composite 統一成「routes 由 routes 組成」後,產生操作計畫又變簡單。

反例對照:FLYWEIGHT 不是領域模式——它純粹是 Value Object 的實作選項,跟領域模型沒有對應關係。Evans 不打算列一份「可當領域模式的設計模式清單」,唯一要求是:模式必須能表達概念性的領域意涵,而非僅僅是技術問題的技術解法。

3. 重構邁向深層理解的完整圖景(第13章)

第13章把整個 Part III 收成一幅圖。需要同時聚焦三件事:活在領域之中、不斷換角度看、與專家維持不間斷的對話。重構的觸發點不只是「壞程式碼」——更重要的觸發是模型語言和領域脫節(這是 Evans 重構觀和傳統重構最大的差異)。

實務工具:探索團隊(Exploration Teams)——2-3 個擅長建模的開發者 + 領域專家,到會議室或咖啡廳腦力激盪半小時到一個半小時,畫 UML、走情境、確認專家認為有用。關鍵是自主、控制範圍、讓想法沉澱(卡住代表一次處理太多、該縮小範圍)。

時機論很重要:「如果你等到能為一個變更做出完整論證,那就已經等太久了。」 大多數團隊對重構太保守——他們看得見修改的風險,卻看不見「維持笨拙設計的風險和繞過它的成本」。Evans 用生物學的「間斷平衡」類比:長期穩定精煉被短暫劇烈變化(突破)打斷——而危機往往就是進步的訊號,意味著團隊已經到達了能看出舊模型拙劣的新高度。

注意事項

⚠️ 分析模式 vs 設計模式,別搞混兩者層級。 分析模式(Fowler)是領域層的模型片段(Account、Posting Rule),講「這個業務概念怎麼建模」;設計模式(GoF)是技術層的結構(Strategy、Composite),講「這段程式碼怎麼組織」。Evans 把後者拉到領域層用時,特別加了「必須契合領域概念」的門檻。

⚠️ 這集是「程式碼設計三本怎麼搭」最直接的章節,但別搶最後一集的收束。 這集示範的是「在 DDD 的建模過程中,怎麼把設計模式和(分析模式的)前人智慧當養分」。三本書整體怎麼搭讀的方法論,留到第 13 集全書收束時完整講。這集點到、引發興趣即可。

⚠️ 第11章那個會計例子裡,開發者最後被迫放棄一個漂亮抽象(因為 ORM 框架和「資料表要能不跑程式就讀懂」的專案標準),改用具體子類。Evans 的態度是:做出經過計算的妥協,然後繼續前進,別讓它偏離模型驅動設計。 這條很重要——DDD 不是理想主義,是在現實阻力下持續往對的方向走。

⚠️ 「設計模式應只在需要時才應用」——Composite 的例子裡 Evans 自己說「在我們需要它之前,沒有 Composite 也運作得很好」。別為了秀模式而提前套用。這是對「模式控」的溫和提醒。

專家補充

💡 第11章的 Posting Rules 例子有個深刻洞見:有些程式碼你根本不懷疑它能從領域模型受益——它起初很簡單、然後機械式地演化,看起來像複雜的 application code 而非領域邏輯。那個 nightly batch 就是這樣。分析模式的價值之一,就是揭示這些盲點。這對聽眾很實用:你 code 裡那些「又臭又長的 batch / 排程 / 規則引擎」,很可能藏著沒被辨識的領域模型。

💡 「程式碼設計三本」在這集的咬合最清楚:重構(第13章)是引擎,分析模式和設計模式是燃料。 Fowler 的《Refactoring》給你「怎麼安全地改」的手法、GoF 給你「改成什麼結構」的目標、分析模式給你「領域該長怎樣」的起點,而 DDD 把這三者統一在「邁向深層理解」這個目的下。沒有 DDD 的領域目的,重構容易淪為「為了乾淨而乾淨」;沒有重構的手法,DDD 的深層模型只是空想。

💡 探索團隊(2-3 人 + 專家、半小時到一個半小時、咖啡廳腦力激盪)這個實務,是現代「Event Storming」工作坊的前身。Event Storming(Alberto Brandolini 提出)把這個過程系統化成「用便利貼在牆上把領域事件貼出來」的協作工作坊,已是當代 DDD 落地的主流第一步。想把 DDD 用起來的聽眾,Event Storming 是比讀 Evans 更快上手的入門。

討論問題

🎙️ 開場鉤子:「每次建模都從白紙開始,太慢也太容易踩前人踩過的坑。這集講怎麼站在前人肩膀上——用 Fowler 的分析模式當起點、用 GoF 的設計模式當零件,但有一個前提:它們得真的『懂』你的領域,而不只是技術上漂亮。」

🎙️ 自問自答:「Strategy 模式什麼時候才算用對在領域層?」——當它對應到一條真實的商業策略或政策(不是技術上的演算法切換)時。如果你的 Strategy 只是「換個排序演算法」,那它是技術模式;如果它是「找最快路線 vs 找最便宜路線」這種業務決策,它才有領域表達力。

🎙️ 帶走的一題:「想想你系統裡那個又長又機械、像 application code 的 batch 或排程——它真的只是程序,還是其實藏著一個沒被你辨識出來的領域模型?」

更大範圍關聯

  • 程式碼設計三本的交會點:這集是 DDD+Design Patterns(GoF)+Refactoring(Fowler)三本書咬合最明顯的章節——重構是引擎、兩種模式是燃料、深層理解是目的(見 [軟體工程領域切分藍圖] §5)。完整的搭讀方法論留到第 13 集收束。
  • Part III 的總結:第13章把突破(EP7)、隱含概念(EP7)、柔性設計(EP8)、模式運用(本集)全部彙整。它論證了一件事:DDD 的重構,觸發點是「模型跟領域脫節」,不只是「程式碼難看」——這是它和 Fowler 重構最大的分野。
  • 連到 Event Storming:探索團隊的腦力激盪實務,是當代 Event Storming 工作坊的雛形,也是想落地 DDD 的最佳入門。
  • 務實主義:「做出經過計算的妥協、繼續前進」呼應 Part IV 的策略設計——DDD 始終是在現實限制下做取捨,不是追求理想模型的潔癖。

錄製建議

  • 建議時長:約 26-28 分鐘(三章合一)。配比:分析模式(第11章)約 9 分、設計模式用在領域層(第12章 Strategy/Composite/FLYWEIGHT 反例)約 9 分、重構總結(第13章 觸發點/探索團隊/時機論/間斷平衡)約 8 分。
  • 討論策略:三章合一,主軸抓「別從零開始 + 模式要契合領域 + 重構是把這一切串起來的引擎」。第11章和第12章用各自的例子(會計 Account、Route Strategy/Composite)帶過即可,重點放在那條「技術模式 vs 領域模式」的分野。第13章的「等到能完整論證才重構就太晚了」和「危機即轉機」是最有觀點、最能引共鳴的金句,留時間講透。
  • 這集做完 Part III 收尾。可以鄭重宣告:「接下來進入全書最被低估、卻最重要的部分——Part IV 策略設計。如果說前面都是『怎麼把一個模型做好』,那麼策略設計回答的是『當系統大到一個模型裝不下時,怎麼辦』。這才是 DDD 在微服務時代重新爆紅的真正原因。」