層與邊界 (Layers and Boundaries)#
架構師常常被認為是「過度設計」的元兇。 為了證明邊界的必要性(或不必要性),Uncle Bob 使用了一個簡單的電腦遊戲:「狩獵 Wumpus (Hunt the Wumpus)」 作為案例。
一、案例:狩獵 Wumpus#
這是一個簡單的文字冒險遊戲。
- 需求: 玩家輸入指令(如 “Move North”),系統回應文字(如 “You smell a Wumpus”)。
- 實作選擇: 我們該如何設計它的架構?
1. 極簡主義 (No Boundaries)#
最簡單的做法是寫一個 Main 元件,裡面包含所有邏輯:讀取輸入、判斷遊戲規則、印出文字。
- 優點: 開發極快,程式碼少。
- 缺點: * 如果老闆突然說:「我們要出西班牙文版!」(語言耦合)。
- 如果老闆說:「我們要改成網頁版!」(UI 耦合)。
- 如果老闆說:「我們要雲端存檔!」(資料儲存耦合)。
- 這時候,你必須重寫整個程式。
2. 整潔架構 (Clean Architecture Boundaries)#
為了預防上述變更,我們設計了完整的邊界:
- UI 層: 獨立於語言(英文/西文)和介面(Console/Web)。
- 遊戲規則層: 純粹的邏輯,不知道輸入來自鍵盤還是滑鼠。
- 資料層: 透過介面儲存狀態(Flash/Cloud)。
這聽起來很棒,但**代價(Cost)**極高。你需要定義大量的介面(Interfaces)、資料傳輸物件(DTOs),處理依賴反轉。對於一個幾百行程式碼的小遊戲來說,這顯然是 過度設計(Over-engineering)。
二、架構師的兩難:預測未來#
這裡揭示了架構師的核心兩難:
- 實作邊界的成本: 建立介面、分離元件、管理依賴非常耗時。如果在專案初期就做全套,可能會因為進度太慢而被開除。
- 忽視邊界的成本: 如果一開始偷懶沒做邊界,當需求變更(如增加多語言支援)來臨時,重構的成本將是天文數字,甚至導致專案失敗。
這是一個賭局:
- 如果你預測未來會有變更,你現在就該建立邊界。
- 如果你預測未來不會有變更,你現在就不該浪費時間建立邊界(YAGNI - You Aren’t Gonna Need It)。
三、結論:保持警惕#
架構師的工作不是一次性地決定所有邊界,而是隨著專案進展持續觀察。
- 初期: 也許不需要完整的邊界,但必須劃分好基本的組件。
- 中期: 當你嗅到「某些需求可能即將變更」的跡象時,就是引入邊界的時機。
- 目標: 在「實作邊界的成本」低於「忽視邊界的成本」的那個交叉點上,精準地介入。
總結: 這需要警惕的心態(Vigilance)。 太早建立邊界是浪費資源;太晚建立邊界是災難。 優秀的架構師會一直盯著這兩個成本曲線,在它們交叉的那一刻果斷行動。