---
# System prepended metadata

title: 依賴注入
tags: [學習筆記, 設計模式, 物件導向]

---

# 依賴注入

###### tags: `學習筆記` `物件導向` `設計模式`

> 當程序到達一定的複雜度，就會需要各種設計模式及原則等工程方法提升程序的可維護性。
> 依賴注入是一般物件導向程式設計的一大重點，依賴注入用的越好程式彈性就越高。
 - 依賴反轉原則 ( Dependency Inversion Principle ) 
 - 控制反轉 ( Inversion of Control )

### 1. 依賴反轉原則 ( Dependency Inversion Principle, DIP )
當自身需要呼叫其他類別的實例時，這樣的關係為==依賴==。
我們真正需要的、依賴的，其實==不是==實際的==類別與物件==，而是他所擁有的==功能==。
這就是依賴反轉原則 DIP (Dependency Inversion Principle):
1. 高階模組不應該依賴於低階模組，兩者都該依賴抽象。
2. 抽象不應該依賴於具體實作方式。
3. 具體實作方式則應該依賴抽象。

> - 高階與低階，是相對關係，其實也就是==呼叫者(Caller)== 與 ==被呼叫者(Callee)==。
> - 抽象，是指==介面(interface)== 或是 ==抽象類別(Abstract Class)==，也就是不知道實作方式，無法直接被實例化。
> - 具體實作方式，就是只有實作介面或是繼承抽象的==非==抽象類別。
> (繼承抽象類別者，有可能還是抽象類別，如以下範例中的 : AbstractB)
```javascript=
abstract class AbstractA {
    // 抽象方法 eat()
    public absract void eat();
}

abstract class AbstractB extends AbstractA {
    /**
     * 可以不實作 父類別 的抽象方法 eat()
     * 因為自己本身也為 抽象類別
     */
    
    // 新增 抽象方法 drink()
    public abstract void drink();
}

/**
 * 具體實作類別
 * 繼承抽象類別 AbstractB
 * 且由於 AbstracB 繼承自 AbstractA
 * 
 * 必須實作 AbstractA 的方法 eat()
 */
class ConcreteC extends AbstractB {
    
    @Override
    public void eat() {
        
    }
    
    @Override
    public void drink() {
        
    }
}

```

### 2. 控制反轉( Inversion of Control, IoC )
**控制反轉( Inversion of Control )** 就是依賴倒置原則的想法去設計的思路，具體採用的方法就是所謂的**依賴注入 (Dependency Injection)** 。
![](https://i.imgur.com/xZ2GBYF.png)

**所謂依賴注入，就是把底層類作為參數傳入上層類，實現上層類對下層類的"控制"。**

---

參考資料來源 : 
 - https://notfalse.net/1/dip#-Dependency
 - https://www.zhihu.com/question/23277575
 - https://segmentfault.com/a/1190000040807826