本章是全書的最終章,將前面介紹的三大策略設計工具——BOUNDED CONTEXTDISTILLATIONLARGE-SCALE STRUCTURE——綜合運用,探討它們如何彼此互補、協同作用,並針對策略設計決策過程提出六項核心原則。

Combining Large-Scale Structures and Bounded Contexts#

LARGE-SCALE STRUCTURE 可以在兩個層次上發揮作用:在單一 BOUNDED CONTEXT 內部組織模型,以及跨越多個 BOUNDED CONTEXT 組織整個 CONTEXT MAP

在單一 BOUNDED CONTEXT 內部#

在非常複雜但統一的模型中,局部結構(如 RESPONSIBILITY LAYERS)能夠提升複雜度的天花板,讓單一 BOUNDED CONTEXT 能夠維護更大規模的模型。

Figure 17.2: Structuring a model within a single BOUNDED CONTEXT

跨越多個 BOUNDED CONTEXT#

許多專案面臨的更大挑戰是理解分散的各個部分如何組合在一起。各部分可能已被劃分到不同的 CONTEXT 中,但每個 CONTEXT 在整體系統中扮演什麼角色、彼此之間如何關聯?此時 LARGE-SCALE STRUCTURE 可以用來組織 CONTEXT MAP,結構的術語適用於整個專案。

Figure 17.3: Structure imposed on the relationships of components of distinct BOUNDED CONTEXTS

與 Legacy System 的整合#

當想採用 RESPONSIBILITY LAYERS 但存在 Legacy System 時,不必放棄分層結構,而是要如實承認 Legacy 在結構中的位置:

  • Legacy 系統提供的 SERVICES 可能實際上只局限於少數幾個層
  • 能夠說出 Legacy 系統適合哪些 RESPONSIBILITY LAYERS,就簡潔地描述了它的範圍與角色
  • 若透過 FACADE 存取 Legacy 系統,可以將 FACADE 提供的每個 SERVICE 設計成歸屬於某一層

Figure 17.4: A structure that allows some components to span layers

團隊也可以在自己的 CONTEXT 內部,採用與 CONTEXT MAP 相同的 LAYERS 來組織模型。

Figure 17.5: The same structure applied within a CONTEXT and across the CONTEXT MAP as a whole

雖然每個 BOUNDED CONTEXT 都是獨立的命名空間,可以各自使用不同的結構,但若走得太遠,會侵蝕 LARGE-SCALE STRUCTURE 作為專案統一概念集的價值。

Combining Large-Scale Structures and Distillation#

LARGE-SCALE STRUCTUREDISTILLATION 的概念彼此互補:

  • LARGE-SCALE STRUCTURE 有助於解釋 CORE DOMAIN 內部的關係,以及 CORE DOMAINGENERIC SUBDOMAINS 之間的關係
  • LARGE-SCALE STRUCTURE 本身可能就是 CORE DOMAIN 的重要組成部分

Figure 17.6: MODULES of the CORE DOMAIN (in bold) and GENERIC SUBDOMAINS are clarified by the layers.

例如,區分 potential、operations、policy 和 decision support 這些層次,本身就萃取出一項對業務問題至關重要的洞見。當專案被劃分為許多 BOUNDED CONTEXTS 時,CORE DOMAIN 的模型物件在大部分專案範圍內不具直接意義,此時這種結構性洞見就特別有用。

Assessment First#

在著手進行策略設計時,必須先對現狀做出清晰的評估。Evans 提出六個關鍵問題:

  1. 繪製 CONTEXT MAP——能否畫出一致的 CONTEXT MAP?是否存在模糊不清的狀況?
  2. 檢視語言的使用——專案上是否存在 UBIQUITOUS LANGUAGE?它是否夠豐富以幫助開發?
  3. 理解什麼是重要的——CORE DOMAIN 是否已被辨識出來?是否有 DOMAIN VISION STATEMENT?能否寫出一份?
  4. 技術是否支持 MODEL-DRIVEN DESIGN——專案的技術選擇是助力還是阻力?
  5. 團隊技術能力——開發人員是否具備必要的技術技能?
  6. 領域知識——開發人員是否了解領域?是否對領域有興趣?

你不會找到完美的答案,目前對專案的了解永遠是最少的。但這些問題提供了堅實的起點。隨著時間推移,可以持續精煉這些答案——特別是 CONTEXT MAPDOMAIN VISION STATEMENT 及其他產出物——以反映變化的情況與新的洞見。

flowchart TD
    Q1{"1. 能否畫出一致的\nContext Map?"} -->|否| Fix1["先釐清系統邊界"]
    Q1 -->|是| Q2{"2. Ubiquitous Language\n是否在使用中?"}
    Q2 -->|否| Fix2["建立團隊共通語言"]
    Q2 -->|是| Q3{"3. Core Domain\n是否已識別?"}
    Q3 -->|否| Fix3["執行 Distillation"]
    Q3 -->|是| Q4{"4. 技術是否支援\nModel-Driven Design?"}
    Q4 -->|否| Fix4["評估技術選型"]
    Q4 -->|是| Q5{"5. 開發者具備\n技術能力?"}
    Q5 -->|否| Fix5["培訓或招募"]
    Q5 -->|是| Q6{"6. 開發者理解\nDomain?"}
    Q6 -->|否| Fix6["加深領域學習"]
    Q6 -->|是| Ready["準備就緒\n開始策略設計"]

Who Sets the Strategy?#

Evans 反對傳統由高高在上的架構團隊預先制定架構的模式,而是介紹了兩種在實務中有效的方式。

Emergent Structure from Application Development#

自律且溝通良好的團隊可以不依賴中央權威,遵循 EVOLVING ORDER 讓秩序有機地生長:

  • 這是典型的 Extreme Programming 團隊模式
  • 結構可能完全自發地從任何 pair programming 組合中浮現
  • 通常由團隊中某位非正式領導者(常是 coach 的角色)負責維持結構的統一性
  • 這位領導者必須仍然是動手寫程式的開發者——是仲裁者與溝通者,而非唯一的構想來源
  • 跨團隊時,各團隊代表可組成非正式委員會來討論結構選項

這種鬆散聯盟的方式在以下條件下較能運作:團隊數量較少、彼此承諾協調、設計能力相當、結構需求夠相似。

A Customer Focused Architecture Team#

當策略需要在多個團隊間共享時,適度集中決策是有吸引力的。架構團隊可以作為各應用團隊的同儕,幫助協調和統一它們的 LARGE-SCALE STRUCTURE 以及 BOUNDED CONTEXT 邊界等跨團隊技術議題。

與傳統架構團隊的關鍵差異:

  • 團隊成員是開發的真正協作者
  • 與開發人員一起發現模式
  • 與不同團隊實驗以達成萃取
  • 親自動手寫程式

Six Essentials for Strategic Design Decision Making#

Evans 提出策略設計決策過程的六項核心原則:

1. Decisions Must Reach the Entire Team#

如果不是所有人都知道策略並遵循它,策略就毫無意義。諷刺的是,象牙塔架構師往往被忽視或繞過——因為他們缺乏親手實踐的回饋,導致方案不切實際。從應用團隊中自然浮現的策略設計,反而更能有效傳達給每個人。

比起管理層賦予的權威,更應關注開發人員與策略之間的實際關係

2. The Decision Process Must Absorb Feedback#

理解專案需求和領域概念所需的深度知識,只有應用開發團隊的成員才具備。這解釋了為什麼架構團隊建立的應用架構很少有幫助——儘管許多架構師的才華不容置疑。

策略設計需要緊密的回饋迴路。Evans 舉例:某技術架構團隊讓自己的成員在各應用開發團隊間輪調,既將實戰經驗帶回架構團隊,也同時傳遞了框架的精妙用法。

3. The Plan Must Allow for Evolution#

有效的軟體開發是高度動態的過程。當最高層級的決策被固化時,團隊在面對變化時的選項就會減少。EVOLVING ORDER 強調根據不斷加深的洞見,持續調整 LARGE-SCALE STRUCTURE

  • 統一原則是有價值的,但它必須隨著專案的生命週期而成長與改變
  • 不應從應用開發者手中拿走太多權力
  • 透過強回饋,創新會在遇到障礙和發現意外機會時自然浮現

4. Architecture Teams Must Not Siphon Off All the Best and Brightest#

管理者傾向將最有技術天賦的開發者調入架構團隊和基礎設施團隊,這常常導致:

  • 應用團隊只剩下技術能力最弱的開發者
  • 建構好的應用程式同樣需要設計技能,這是在為失敗做準備
  • 策略團隊幾乎不會納入領域經驗最豐富的開發者
  • 策略設計並非純技術任務,切斷與領域知識的聯繫會嚴重削弱架構師的努力

所有應用團隊都必須有強力的設計者。任何嘗試策略設計的團隊都必須具備領域知識。有效的策略團隊必須搭配有效的應用團隊。

5. Strategic Design Requires Minimalism and Humility#

DISTILLATION 和極簡主義對任何好的設計工作都是必要的,但對策略設計來說更為關鍵:

  • 即便是最輕微的不合適,都有巨大的潛力成為障礙
  • 獨立的架構團隊必須格外小心,因為他們較難感受到自己可能為應用團隊設下的障礙
  • 每個元素都必須證明自己值得存在——因為幾乎所有東西都會妨礙到某些事情
  • 認識到你最好的想法可能會妨礙到別人,這需要謙遜

6. Objects Are Specialists; Developers Are Generalists#

好的物件設計是讓每個物件有清晰而狹窄的職責,並將相依性降到最低。但團隊互動不應如此:

  • 好的專案中,大家都會關心別人的事情
  • 開發者玩框架,架構師寫應用程式碼,所有人跟所有人交談
  • 這是高效的混沌
  • 讓物件成為專家,讓開發者成為通才

過度專業化會抽掉 Domain-Driven Design 的動力。策略設計從應用設計中浮現,但它需要全局視野;精細設計需要與程式碼緊密合作。試圖將這些切割成不同人的工作,往往適得其反。

mindmap
  root((策略設計決策要點))
    決策須傳達全團隊
      不能只存在於少數人腦中
    流程須吸收回饋
      持續從實作中學習
    計畫須允許演進
      不凍結架構決策
    架構團隊不抽走最強人員
      保持開發團隊能力
    策略設計需極簡與謙遜
      最少限制原則
    物件是專家,開發者是通才
      跨領域理解

The Same Goes for the Technical Frameworks#

技術框架可以大幅加速應用開發,透過提供基礎設施層來解放應用程式、幫助隔離領域與其他關注點。但框架也有干擾領域模型表達性實作和阻礙變更的風險。

限制策略設計負面影響的同一組偏見,同樣適用於技術架構:

  • Evolution——持續演進
  • Minimalism——極簡主義
  • Involvement with the application development team——與應用開發團隊深度參與

不遵循這條路的架構,要麼扼殺應用開發的創造力,要麼被繞過而形同虛設。

Don’t Write Frameworks for Dummies#

Evans 對框架設計者提出嚴厲警告:

  • 假設某些開發者不夠聰明去做設計,這種團隊分工很可能失敗——因為它低估了應用開發的困難度
  • 如果他們不夠聰明去設計,就不應該被指派去開發軟體;如果他們夠聰明,那麼溺愛式的做法只會在他們和所需工具之間築起障礙
  • 判斷框架是否走對方向:問框架設計者他們對使用者的期望——如果設計者對框架使用者展現高度尊重,他們很可能走在正確的道路上

Beware the Master Plan#

Evans 引用 Christopher Alexander 等建築師在《The Oregon Experiment》中對 Master Plan 的批判,作為全書的收尾:

  • Master Plan 試圖設定足夠的指導方針,以確保環境整體的一致性,同時為個別建築留下適應在地需求的自由
  • 但在實務上,Master Plan 失敗了——因為它們創造的是極權式的秩序,而非有機的秩序
  • 它們太僵硬,無法輕易適應不可避免的自然與不可預測的變化
  • Master Plan 既太精確(整體)又不夠精確(細節)
  • 它使社群成員疏離,因為大多數重要決策已經被預先決定

Alexander 及其同事倡導的替代方案是:為所有社群成員提供一組原則,應用於每一次漸進式的成長行動,讓「有機的秩序」自然浮現,良好地適應環境。

這與 Evans 在全書中的主張完全呼應:不追求一開始就完美的宏大設計,而是透過 EVOLVING ORDER、持續的 DISTILLATION 與緊密的回饋迴路,讓設計隨著對領域理解的加深而有機演化。