🎯 什麼情境該想到我

當你「系統裡有一塊邊界不清、模型混亂、無法(或不值得)用乾淨模型去救的既有區域」的時候。你需要務實地承認它、把它圈起來,並防止它的混亂蔓延污染其他部分。

⚙️ 怎麼用(步驟 / 公式)

意圖:辨識既有系統中模型混雜、邊界模糊的區塊,明確地把它整個圈成「一個」限界上下文,接受它內部沒有乾淨模型,並築牆阻止它向外蔓延污染其他上下文。

做法要點:

  1. 在上下文對應上誠實標出這團混亂,把它整塊劃為一個大泥球上下文。
  2. 不要嘗試在裡面套用嚴謹的領域模型或通用語言——對它降低期望。
  3. 在它與外界之間建立防腐層,防止它的混亂概念滲進其他乾淨上下文。
  4. 集中精力守護外部乾淨區域;對泥球本身採維持現狀、必要時逐步收斂的策略。

★★ Evans 的用法很特別:它是一個「地圖標記」,不是一個罵人的詞

★★ 在 [[上下文對應]] 上,「大泥球」是一個正當的標記:
  ★ 「這一塊沒有清楚的模型邊界、概念混雜、我們不打算在裡面做 DDD」
→ ★ 它的價值是:★★ 明確劃出它的範圍,★ 並在邊界上建立防護
→ ★★ 而不是「我們要重寫它」(★ 那通常不會發生)

★★ 這是這一頁最重要的觀念轉換:
★ 大泥球不是一個「待修的 bug」,而是一個要被管理的現實。
★★ 你的目標不是消滅它,是「不讓它擴散」。

★★ 三個可觀察的特徵(用來判斷「這塊是不是大泥球」)

① ★★ 同一個名詞在同一塊程式碼裡有多種意義
   ★ 「用戶」有時指登入帳號、有時指付款人、有時指收件人
   → ★ 而且沒有任何型別區分它們(★★ 全部是 string userID)

② ★★ 不變式無處可尋
   ★ 「已出貨不可取消」這條規則在五個地方各檢查一次,★ 而其中兩個寫錯
   → ★ 判準:★★ 你能指出「這條規則的唯一守點」嗎?不能 → 大泥球

③ ★★ 任何改動的影響範圍無法預測
   ★ 改一個欄位 → ★ 不知道會影響什麼,只能靠 QA 全面回歸
   → ★ 這是最實際的判準:★★ 「你敢不敢改?」

★★ 邊界防護:這是唯一真正有效的策略

★ 四個具體動作(★ 按投資報酬率排序):

① ★★ 在邊界建立 [[防腐層]](★ 最重要)
   ★ 新的上下文絕不直接 import 大泥球的型別
   → ★★ 用 depguard 讓它變成 CI 紅燈
   → ★ 這一步的價值:★★ 大泥球的混亂「止步於此」

② ★★ 把大泥球當成一個外部系統看待
   ★ 它有一組(可能很醜的)API/資料表 → ★ 你只透過那組介面用它
   → ★★ 心態轉換:★ 不要試圖「理解它的模型」,★ 只要知道「怎麼跟它講話」

③ ★★ 用 [[工具-特徵測試]] 圍住你要改的那一小塊
   ★ 不理解它 → ★ 先寫測試記錄「它現在做什麼」
   → ★★ 這是 [[修改程式碼的藝術]] 的核心手法(見 [[工具-遺留程式碼修改流程]])

④ ★ 新功能一律放在新的上下文裡
   → ★★ 這是「不讓它擴散」最直接的手段
   → ★ 見 [[工具-服務邊界與演進式拆分]] 的絞殺者模式

★★ ①的具體做法:

# ★ depguard:新的上下文不得 import legacy
depguard:
  rules:
    newcontexts:
      files: ["**/internal/ordering/**", "**/internal/billing/**"]
      deny: [{ pkg: "myapp/internal/legacy" }]

★★ 什麼時候不該碰它(★ 這是最務實的一段)

★★ 大泥球值不值得整理,看三件事:
① ★ 它「會不會改」?
   ★ 一年改兩次 → ★★ 不要碰。★ 整理它的成本永遠收不回來
② ★ 它「會不會擴散」?
   ★ 已經圍住了(有防腐層、新功能不進去)→ ★★ 讓它待著
③ ★★ 它是不是核心子領域?
   ★ 是 → ★ 那它遲早要處理(★★ 核心不該是大泥球)
   ★ 不是 → ★ 圍住它就夠了

★★ 判準:★ 「不改它會出事嗎?」
不會 → ★★ 不要碰。 ★ 這不是逃避——它是把有限的力氣放在會回本的地方。

★ 最常見的錯誤是「重寫」:★★ 重寫一個大泥球的成功率極低,
因為它的複雜度大部分來自「那些你不知道的業務規則」,
而那些規則只存在於它的程式碼裡。

★★ 如果它確實必須處理:一條可行的路徑

第 1 步 ★★ 圍住它(防腐層 + depguard + 新功能不進去)← ★ 先止血
第 2 步 ★★ 用特徵測試記錄現有行為(★ 從「最常改的那一塊」開始)
第 3 步 ★ 從邊緣切出一小塊到新的上下文(★ 絞殺者模式)
第 4 步 ★★ 讓大泥球的那一塊變成對新上下文的轉發
第 5 步 ★ 重複 3–4,★★ 而且每一步都可以停在那裡

★★ 「每一步都可以停」是這條路徑的關鍵性質:
★ 它讓「重構遺留系統」變成一個可以隨時因為優先順序改變而暫停的計畫,
而不是一個必須做完才有價值的大工程。

★ 兄弟辨析

差別
各行其道★ 刻意不整合的清楚邊界
防腐層★ 大泥球邊界防護的主要手段
限界上下文★ 大泥球就是「沒有清楚邊界」的區塊
過大類別★ 類別層級的同一現象

🧪 我實際套用的紀錄

  • (待填)

⚠️ 注意 / 什麼時候不適用

  • 它是一種務實的「承認現實」,不是鼓勵製造爛系統;別把它當成放任亂寫的藉口。

  • 不要在泥球內部投入大量心力硬做乾淨建模,投報通常很差;重點在「圈住+隔離」。

  • 若這塊其實是核心領域,長期仍需規劃重寫或拆解,不能永遠只圈著。

  • ★★ 大泥球在上下文對應上是一個正當的「地圖標記」,不是罵人的詞。目標不是消滅它,是「不讓它擴散」。

  • ★★ 判準:「不改它會出事嗎?」不會 → 不要碰。 一年改兩次的東西,整理成本永遠收不回來。

  • ★★ 重寫的成功率極低,因為它的複雜度大部分來自「那些你不知道的業務規則」,而那些規則只存在於它的程式碼裡。

  • ★★ 邊界防護(防腐層 + depguard + 新功能不進去)是唯一真正有效的策略。

  • ★★ 心態轉換:把它當成一個外部系統——不要試圖理解它的模型,只要知道怎麼跟它講話。

  • ★★ 「每一步都可以停」是遷移路徑的關鍵性質,讓它變成可暫停的計畫而非必須做完的大工程。

  • ★ 判準:你能指出「這條規則的唯一守點」嗎? 不能 → 大泥球。

  • ★ 核心子領域不該是大泥球,那遲早要處理;不是核心的,圍住就夠了。

  • ★ 不理解它就先寫 工具-特徵測試 記錄現有行為,不要靠閱讀推測。

🔗 相關工具