跳轉到主要內容
類別: 原則
類型: 物件導向設計原則
來源: Northeastern University 的 Demeter Project,約 1987 年由 Ian Holland 等提出
別名: 最少知識原則
快速回答迪米特法則(Law of Demeter)主張:模組應只與直接協作者溝通,不要穿透多層物件內部結構。它的核心作用是降低耦合,讓系統在結構調整時更穩定。

什麼是迪米特法則?

迪米特法則(Law of Demeter)是一條邊界規則:方法應只呼叫自己、直接欄位、參數,以及在方法內新建物件的方法。
讓直接協作者完成你要的動作,比自己一路鑽進別人的內部結構更不容易壞。
在程式碼上,最常見的實踐是避免 a.getB().getC().doX() 這類火車式呼叫鏈。它與單一職責原則關注點分離快速失敗原則搭配時,能有效降低變更外溢。

迪米特法則的三層理解

  • 入門:少寫深層鏈式呼叫,改由直接對象提供行為。
  • 實踐:透過意圖明確的門面方法隱藏內部導航。
  • 進階:把它當成控制變更半徑的架構邊界工具。

起源

迪米特法則源自 1980 年代後期 Northeastern University 的 Demeter Project,並在 Ian Holland 的研究及相關工程文獻中被系統化。 它要解決的核心問題是維護成本:當呼叫方深度依賴被呼叫方的內部結構時,內部微小調整就可能造成跨模組連鎖破壞。 因此,限制互動在「近距離協作」可顯著降低耦合與回歸風險,這也是它後來成為常見設計原則的原因。

核心要點

迪米特法則不是語法潔癖,而是溝通邊界管理。
1

只與朋友溝通,不碰陌生內部

方法應聚焦在自己與直接協作者,避免跨多層物件取值。
2

把深層取值改成意圖方法

由直接協作者暴露業務意圖方法,呼叫方不需知道內部物件圖。
3

把長呼叫鏈視為重構訊號

呼叫鏈越長,通常代表責任分配或邊界設計有待調整。
4

在純度與可讀性間取平衡

為了形式合規而大量加包裝層,可能讓程式更難理解與維護。

應用場景

這條原則可落在開發流程與團隊規範中。

後端服務分層

以服務層意圖方法取代深層資料物件鏈式讀取,降低跨層依賴。

前端狀態管理

透過 selector 與 adapter 隔離深層結構,避免元件耦合擴散。

SDK 與函式庫 API

提供穩定入口 API,避免使用者依賴內部物件結構細節。

團隊程式碼審查

將火車式呼叫鏈列為耦合熱點,優先安排重構。

經典案例

在訂單與結算類系統重構中,常見做法是把深層物件導航改為聚合邊界上的門面方法。多個公開工程經驗都指出,這樣能減少模型變更造成的連鎖修改。 可追蹤指標通常是「每個需求涉及的檔案數」與「發版後回歸缺陷數」。當呼叫深度降低、邊界穩定後,兩項指標往往同步改善,表示變更面被有效收斂。

邊界與失效場景

迪米特法則若過度套用,也會出現副作用。
  • 包裝層膨脹:過多中轉方法使程式語意變弱、可讀性下降。
  • 介面過度瘦身:隱藏過多細節會壓縮合理的進階組合能力。
  • 形式正確、語義耦合:看似符合規則,但實際依賴仍可能很重。

常見誤區

實務上常被誤解成「只要禁用點號鏈式呼叫就好」。
更正:語義穩定的 fluent API 與洩漏內部結構的深層導航應分開判斷。
更正:只有能表達意圖並隔離變更的封裝才真正有價值。
更正:核心是局部互動、控制外溢,在各種架構都適用。

相關概念

迪米特法則與相鄰原則協同時效果最佳。

單一職責原則

明確職責邊界,有助於降低跨模組不必要的相依。

關注點分離

先分好層次與責任,才能避免深層穿透呼叫。

最小權限原則

在安全設計中採用同樣思路:只給最小必要存取範圍。

一句話總結

迪米特法則透過「只和直接協作者互動」來收斂耦合,讓系統在變更時更可控。