控制反轉 (Inversion of Control) vs 依賴反轉 (Dependency Inversion)
兩者不相等!
依賴倒置原則 (Dependency Inversion Principle, DIP) :
高階模組不應該依賴於低階模組,兩者都該依賴抽象。
抽象不應該依賴於具體實作方式。
具體實作方式則應該依賴抽象。
舉例來說,此程式違反了 依賴倒置原則, 它使高階模組 (Computer) 依賴 低階模組 (英雄聯盟):
====================================================================
class Computer {
// 依賴於低階模組:『具體』的英雄聯盟,而非 『抽象』的遊戲
private 英雄聯盟 lol;
public Computer() {
// 預設安裝遊戲: 英雄聯盟
lol = new 英雄聯盟();
}
public Computer(英雄聯盟 lol) {
this.lol = lol;
}
public void playGame() {
if (lol != null)
lol.play();
}
}
class 英雄聯盟 {
public void play() {
System.out.print("德瑪西雅~");
}
}
====================================================================
然而,他還是能透過 IoC/DI ,
被動取得 類別 “英雄聯盟” 的實例 lol:
解除了 高階模組 (Computer) 主動對 低階元件 (英雄聯盟) 的實例方式,
卻 解除不了 高階模組 對 低階模組 的 依賴關係。
因為 高階模組 依賴的是 具體實作 (英雄聯盟),
而非 抽象 (介面 or 抽象類別)。
如果想實現 依賴倒置原則 ?
還記得 依賴倒置原則 (Dependency Inversion Principle, DIP) 的結尾嗎?
僅僅將『 高階模組的依賴對象,由具體改為抽象 』,是 不夠 的,
因為高階模組 欲使用 低階模組的物件時,還是 需要自己 new 具體實作類別。
高階模組,依賴於抽象,而非低階模組。
但 要使用 該抽象的 具體產品 (低階模組) 時,
不用也不需要知道是哪種 具體產品
不再自己實例 具體產品,而是 服務容器 會提供給他 。
Reference:
https://notfalse.net/3/ioc-di