> ## Documentation Index
> Fetch the complete documentation index at: https://meta.niceshare.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 迪米特法則

> 迪米特法則要求模組只與直接協作者互動，避免深層呼叫鏈。掌握其起源、落地方法與過度套用時的風險。

<Info>
  **類別**: 原則<br />
  **類型**: 物件導向設計原則<br />
  **來源**: Northeastern University 的 Demeter Project，約 1987 年由 Ian Holland 等提出<br />
  **別名**: 最少知識原則
</Info>

<Note>
  **快速回答** — **迪米特法則**（Law of Demeter）主張：模組應只與直接協作者溝通，不要穿透多層物件內部結構。它的核心作用是降低耦合，讓系統在結構調整時更穩定。
</Note>

## 什麼是迪米特法則？

**迪米特法則**（Law of Demeter）是一條邊界規則：方法應只呼叫自己、直接欄位、參數，以及在方法內新建物件的方法。

> 讓直接協作者完成你要的動作，比自己一路鑽進別人的內部結構更不容易壞。

在程式碼上，最常見的實踐是避免 `a.getB().getC().doX()` 這類火車式呼叫鏈。它與[單一職責原則](/zh-hant/principles/single-responsibility)、[關注點分離](/zh-hant/principles/separation-of-concerns)、[快速失敗原則](/zh-hant/principles/fail-fast)搭配時，能有效降低變更外溢。

### 迪米特法則的三層理解

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

## 起源

迪米特法則源自 1980 年代後期 Northeastern University 的 Demeter Project，並在 Ian Holland 的研究及相關工程文獻中被系統化。

它要解決的核心問題是維護成本：當呼叫方深度依賴被呼叫方的內部結構時，內部微小調整就可能造成跨模組連鎖破壞。

因此，限制互動在「近距離協作」可顯著降低耦合與回歸風險，這也是它後來成為常見設計原則的原因。

## 核心要點

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

<Steps>
  <Step title="只與朋友溝通，不碰陌生內部">
    方法應聚焦在自己與直接協作者，避免跨多層物件取值。
  </Step>

  <Step title="把深層取值改成意圖方法">
    由直接協作者暴露業務意圖方法，呼叫方不需知道內部物件圖。
  </Step>

  <Step title="把長呼叫鏈視為重構訊號">
    呼叫鏈越長，通常代表責任分配或邊界設計有待調整。
  </Step>

  <Step title="在純度與可讀性間取平衡">
    為了形式合規而大量加包裝層，可能讓程式更難理解與維護。
  </Step>
</Steps>

## 應用場景

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

<CardGroup cols={2}>
  <Card title="後端服務分層">
    以服務層意圖方法取代深層資料物件鏈式讀取，降低跨層依賴。
  </Card>

  <Card title="前端狀態管理">
    透過 selector 與 adapter 隔離深層結構，避免元件耦合擴散。
  </Card>

  <Card title="SDK 與函式庫 API">
    提供穩定入口 API，避免使用者依賴內部物件結構細節。
  </Card>

  <Card title="團隊程式碼審查">
    將火車式呼叫鏈列為耦合熱點，優先安排重構。
  </Card>
</CardGroup>

## 經典案例

在訂單與結算類系統重構中，常見做法是把深層物件導航改為聚合邊界上的門面方法。多個公開工程經驗都指出，這樣能減少模型變更造成的連鎖修改。

可追蹤指標通常是「每個需求涉及的檔案數」與「發版後回歸缺陷數」。當呼叫深度降低、邊界穩定後，兩項指標往往同步改善，表示變更面被有效收斂。

## 邊界與失效場景

迪米特法則若過度套用，也會出現副作用。

* **包裝層膨脹**：過多中轉方法使程式語意變弱、可讀性下降。
* **介面過度瘦身**：隱藏過多細節會壓縮合理的進階組合能力。
* **形式正確、語義耦合**：看似符合規則，但實際依賴仍可能很重。

## 常見誤區

實務上常被誤解成「只要禁用點號鏈式呼叫就好」。

<AccordionGroup>
  <Accordion title="誤區：所有鏈式呼叫都違反迪米特法則">
    **更正**：語義穩定的 fluent API 與洩漏內部結構的深層導航應分開判斷。
  </Accordion>

  <Accordion title="誤區：包裝方法越多越好">
    **更正**：只有能表達意圖並隔離變更的封裝才真正有價值。
  </Accordion>

  <Accordion title="誤區：它只是 OOP 教條">
    **更正**：核心是局部互動、控制外溢，在各種架構都適用。
  </Accordion>
</AccordionGroup>

## 相關概念

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

<CardGroup cols={3}>
  <Card title="單一職責原則" href="/zh-hant/principles/single-responsibility">
    明確職責邊界，有助於降低跨模組不必要的相依。
  </Card>

  <Card title="關注點分離" href="/zh-hant/principles/separation-of-concerns">
    先分好層次與責任，才能避免深層穿透呼叫。
  </Card>

  <Card title="最小權限原則" href="/zh-hant/principles/least-privilege">
    在安全設計中採用同樣思路：只給最小必要存取範圍。
  </Card>
</CardGroup>

## 一句話總結

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