依賴(Dependencies)
當類別A裡面使用到類別B,像是A裡面的某個函式必須用到類別B時,我們說類別 A 依賴類別 B。
1. 好的與壞的依賴關係
依賴關係有兩種度量方向:
- 內聚(cohesion)
- 耦合(coupling)
簡單的說,內聚代表功能相關的類別互相依賴的程度。
耦合與內聚的觀念是相對的,代表功能並不相關的類別或模組之間互相依賴的程度。
在軟體開發上,為了程式的可讀性、擴展性……等,會建議程式碼有高的內聚度,以及低的耦合度。所以我們應該盡可能把相關的功能放進一個模組(這邊所說的模組不專指 Yii 模組,也不是某個類別,而是一種邏輯概念)。在這個模組裡面,可以不用過度抽象化,直接使用相依的程式類別運作。
而被這個模組所使用,但是並不屬於該模組的其他類別,則不應該直接使用。而應該透過介面(interface)以降低耦合度。
透過介面,模組可以得到自己運作所需要的東西,並且不和模組外的類別互相依賴。
2. 達成低耦合
我們不可能完全消除程式之間的依賴,但是我們可以盡可能使程式碼的彈性提高。
3. 控制反轉
控制反轉(inversion of control,IoC)的原則,是用來降低程式之間的耦合度。
4. 依賴注入
依賴注入(Dependency injection,DI),控制反轉的一種形式。
5. 依賴注入容器
基本的依賴注入並不困難。我們選擇某個不關心依賴關係的地方,通常是不會進行單元測試的控制器,來建立需要依賴關係的物件,並將其傳遞給相依的類別。
在沒有很多依賴關係,依賴關係之間也沒有出現巢狀結構時,這種方式可以運行的很好。
不過如果依賴關係變多,並且依賴關係之中又有其他依賴關係時,建立整個架構就會變得非常的繁瑣,需要大量的程式碼,並且可能出現很難偵錯的問題。
另外,對多數依賴關係來說,其實需要的東西是一樣的,就好像某種第三方 API 包裝一樣。
所以對框架來說:
- 一次定義如何建立這樣的 API 包裝
- 每次請求時,才實例化該 API
是很合理的設計。
這就是 Yii 提供依賴注入容器(DI Container)的用途了。
更多資訊可以參考對 Yii 依賴注入容器的官方教學。