---
# System prepended metadata

title: '控制反轉與依賴注入 '
tags: [solid, oop]

---

# IoC(控制反轉)and DI(依賴注入)

### Ioc (Inversion of Control) 控制反轉
Ioc控制反轉 是 oop物件導向 中一個很重要的程式設計概念，為的就是降低程式碼的耦合度。

而在程式碼中會出現許多兩個物件合作的情況，但若是使用 new xxx 的寫法，會造成兩個物件的高度耦合。

假設今天程式碼中有 A , B 和 C Class 三個類別，而 A, C Class 需要使用 B 提供的某個方法，就需要在 A, C Class 中 new 一個 B ，再去呼叫這個 B 物件的方法。這時若是修改 B 的方法，則 A, C 也需要對應的修改程式碼，**這種情況是我們不樂見的，因為隨著依賴關係變成一對多、程式會越來越龐大的時候，這種情況會越常出現、越複雜，造成修改程式碼的難度，這就是耦合度太高的問題。**
* 為了解決這種情況，就提出了 IoC(控制反轉) 的概念。

IoC(控制反轉)主要是說兩段程式碼(類別)不應該彼此依賴，反而應該將功能交給第三方，需要時去第三方呼叫，這個第三方可以是介面、框架、或是建構函數

用原本的舉例，原本的控制權是 A Class 控制著 B Class，但現在控制權被給到第三方了，A Class 需要甚麼就跟第三方呼叫，再經由第三方去操控 B Class，這時控制權就被反轉了。從 A, C 依賴 B 變成 A, C 依賴第三方，第三方依賴 B。

### DI (Dependency Injection) 依賴注入
DI依賴注入 是實作 Ioc控制反轉 的一個方法，做法是把被**依賴**物件**注入**第三方裡。

具體作法是原本要呼叫的 B Class 服務，先交由第三方用函數包起來，或是使用參數傳遞的方法，實作細節可以看下面的推薦網站。這樣可以減少修改程式的範圍只到第三方為止，因為第三方的函數確定了接下來往後傳下去的資料格式。

當 A, C Class 需要使用 B Class 提供的某個服務時，只需要呼叫第三方或使用參數傳遞(透過第三方直接呼叫 B)。如此一來，將來修改時，會影響到的部分只有第三方和 B Class。





---
推薦網站 : 
很淺顯易懂的解釋 : [IOC(控制反轉) ， DI(依賴注入) 深入淺出~~ |石頭的coding之路](https://dotblogs.com.tw/daniel/2018/01/17/140435)
，[維基百科](https://zh.wikipedia.org/zh-tw/%E6%8E%A7%E5%88%B6%E5%8F%8D%E8%BD%AC)

參數傳遞的實作細節 : [Ioc(控制反轉)/DI(依賴注入)](https://welson327.gitbooks.io/java-spring/content/spring/ioc_di.html)