引子:第一天上班的鬱悶#

小菜第一天去公司,主管不在:

  • 人事小楊只認識 IT 部的小張,把小菜介紹給小張就走了
  • 小張臨時要去客戶那邊處理 PC 故障,要小菜等
  • IT 部還有兩個人在,但都不是負責人——一個忙 QQ、一個看新聞
  • 小菜不認識小李,小李說「這事是小張負責的,我不管」
  • 小菜在椅子上坐了一個上午,靠看《重構》打發時間
  • 直到小張快下班才回來,半小時搞定 Ghost 還原

沒有管理、單靠人際關係協調是很難辦成事的。

「一個和尚挑水吃,兩個和尚抬水吃,三個和尚沒水吃。」

問題出在哪?#

如果有 IT 主管負責分配任務,任何人需要 IT 部協助都找主管安排——主管自然會看誰有空、誰負責,小張不在還可以指派小李。

如果連主管都不在,制度上應該規定「誰有空誰先處理,事後再向主管彙報」,公司不應該因為一個人不在就停擺。

打電話應該怎麼問?

  • 不該問:「經理在嗎?」「小張在嗎?」——這是依賴具體實作
  • 應該問:「IT 部嗎?我電腦壞了,請派人來修。」——這是依賴抽象介面

這呼應了第 5 章的依賴倒轉原則(DIP):面向介面編程,不要面向實現編程。

IT 部對應抽象類或介面,小張、小李對應具體類。

flowchart LR
    subgraph 反例[無中介者:員工自己找具體工程師]
        E1[員工小菜] --> A[小張]
        E1 --> B[小李]
        E1 --> C[小王]
    end
    subgraph 正例[有 IT 部主管:星形協調]
        E2[員工小菜] --> M[IT 部主管]
        M --> A2[小張]
        M --> B2[小李]
        M --> C2[小王]
    end

迪米特法則(LoD)#

迪米特法則(Law of Demeter, LoD),也叫最少知識原則

如果兩個類別不必彼此直接通訊,那麼這兩個類別就不應當發生直接的相互作用。如果其中一個類別需要呼叫另一個類別的某一個方法,可以透過第三者轉發這個呼叫。[J&DP]

兩個前提#

  1. 降低成員的訪問權限

    • 每個類別應盡量包裝好自己的 private 狀態
    • 不需讓別的類別知道的欄位或行為就不要公開
    • 對外部提供需要訪問的部分,通常用屬性(property)
  2. 強調類別之間的鬆耦合

    • 類別之間耦合越弱,越有利於複用
    • 處在弱耦合的類別被修改,不會對有關係的類別造成波及

資訊的隱藏促進了軟體的複用。

應用於故事#

對小菜而言:

  • IT 部是抽象的窗口
  • 即使裡面的人都離職換了新人,電腦出問題還是可以找 IT 部解決
  • 不需要認識具體的同事,也不需要靠關係
  • 真要認識,只要認識 IT 部的主管就可以了,由他來安排工作

迪米特法則與封裝、依賴倒轉原則並不矛盾——它們都是物件導向設計的不同面向,共同服務於降低耦合、提升複用這個核心目標。