淺談Coupling 耦合, Dependency Injection 依賴注入及Dependency Inversion Principle 依賴反轉。

Jun
appxtech
Published in
8 min readJul 17, 2020

Coupling:耦合(Dependency依賴)

Dependency Injection:依賴注入

Dependency Inversion Principle:依賴反轉

在學習Java之中,上面的三個重要是非常重要的觀念,程式在需求不斷的調整過程中,一定會不停的修改調整,一個好的程式具備的其中之一條件,就是「易於維護」。接下來就各別淺談說明。

什麼是Coupling(耦合)

Coupling 耦合又可稱為(Dependency 依賴),簡單的說就是程式與程式之間的相互依賴性。依賴性愈高,代表著後續維護愈繁雜。

下面會用程式與情景來說明。情境舉例,一個國小的教室(ClassRoom),需要一個數學老師(MathTeacher)教學。「師者,所以傳道、受業、解惑也。(師說.韓愈)」,因此老師具備傳道(Teaching),受業(Test),解惑(QA)這三項技能(Methods),而數學老師(MathTeacher)會在教室(ClassRoom)裡,進行這三項技能(Methods)。

因此,把上述的情景轉換成程式碼,會變成如下:

左邊為數學老師,右邊為在教室中指派一位數學老師
執行結果

當今天教室需要進行教學、考試或提問時,就會請老師去執行他的技能(Methods)。但是當今天數學老師要改成英文老師(EnglishTeacher)時,會怎麼修改?左邊數學老師會去修改成英文老師,而右邊第5行,會把MathTeacher 改成EnglishTeacher 。因為一個程式的變動,以致另一程式也需要隨之更改,這就是高耦合Coupling。且這樣的寫法,會導致教室只能讓數學老師使用,因為數學老師MathTeacher是在教室ClassRoom這裡產生(new 出來)的。

Dependency Injection:依賴注入

為能解決高耦合Coupling的情況,以減少程式的修改,因此會使用Dependency Injection(依賴注入),來解決程式與程式之間過度依賴的情況。

使用 建構子(Contructor)

首先,新增一個Teacher 的class (老師類別),將老師的技能(Methods)寫入,可以隨需求更改教學的內容。

接下來使用建構子,將教室(ClassRoom)程式做修改

第5行的地方,ClassRoom新增Teacher這個類別,並且透過建構子,將傳入的Teacher物件指向ClassRoom的Teacher。

上述的說明可能很難理解,下面改用情境來說明。Dependency Injection(依賴注入)的修改,就是重新訂立教室(ClassRoom)的使用規則,程式第5行,指派一位老師(Teacher),無論老師是誰、教的內容是什麼。而程式第8行,當要使用教室時,該指派過來的老師,成為這間教室的指定老師。

而在執行的時候,只要在使用ClassRoom之前,新增一位老師,並且送到教室去就可以了,下面是執行的結果

下面做了二張圖,以說明透過Dependency Injection(依賴注入),讓程式與程式之間的耦合性Coupling降低,減少當某一程式變動時,另一種式也需要修改的情況。

老師教學內容為數學
老師教學內容為英文

從上面二張圖的執行結果,可以發現若要變換老師的教學內容,只需修改Teacher的Methods內容即可,而主程式(ElementarySchool)及教室(ClassRoom)的程式完全不需要變動。這樣一來是不是就讓維護變的更簡單了,這就是Dependency Injection(依賴注入)的好處。

Dependency Inversion Principle:依賴反轉

Dependency Inversion Principle:依賴反轉,又稱為依賴反向或依賴倒轉。

當程式開發愈來愈多功能時,也代表著程式需要更大更廣的彈性。以上述的情境來說,我們多新增三個條件:1、教室可以有很多間。2、有多個不同的老師。3、老師在教室用相同的教學方法但教不同的內容。

光是聽到這樣可能思考上就會打結了,到底要怎麼做呢?我們可以從透過描述情境先將邏輯整理出來。

情境描述:不同老師教內容雖然都不同,但為了有相同的技能和教學方法,這些老師們都必需要從同一個師範大學畢業,這樣學的教學方法才會一致。畢業後到國小教書,而國小將不同老師分派到不同的教室,以進行在師範大學中所學到的教學方法。

透過上述的情景,我們整理出的邏輯順序如下
1、有一個師範大學,教導制式化的教學方法
2、老師們在師範大學裡,學到制式化的教學方法,但教的內容是自己的專業科目內容。
3、國小教室的老師只接受有受過師範大學的老師來上課
4、國小將老師分派到不同間的教室中
5、每間教室的老師用在師範大學中的制式教學方法

這樣的情境描述,是否比較清楚條件內容了,接下來會繼續用原本的例子完成上述的修改。

1、有一個師範大學,教導制式化的技能與教學方式

建立一個Interface(師範大學),去訂立規定的Meathods(制式化的教學方式)

2、老師們在師範大學裡,學到制式化的技能與教學方式,但教的內容是自己的專業科目內容。

建立多個老師(Teacher),透過實做(implements)師範大學(interface class)的方式,學會制式化教學方法(Meathods)。

建立數學老師(MathTeacher),Java老師(JavaTeacher)及英文老師(EnglishTeacher),並實作(implements)師範大學(NormalSchool interface class)的方式,學會制式化的三項教學方法(Meathods),分別為Teaching(),Test(),QA()。但教學的內容各自去定義。

3、國小教室的老師只接受有受過師範大學的老師來上課

修改教室(ClassRoom)的老師為只接受從師範大學(NormalSchool)的人。

第5行指定教室內的老師teacher為師範大學(NormalSchool)出來的人,程式第7–8行,規定(Constructor建構子)當教室建立時,就必需指派一位師範大學(NormalSchool)畢業的老師來教課,程式12、16、20行,教課的內容為師範大學(NormalSchool)制式化的教學方法。

4、國小將老師分派到不同間的教室中

1.聘顧(新增)三位老師,分別為MathTeacher(), JavaTeacher()及EnglishTeacher()。
2.因為三位老師都是(implements)師範大學(interface class)的,所以類別可以訂為NormalSchool(interface class)。
3.新增3間教室,分別為class1, class2及class3。因為教室的規定(Constructor建構子),當新增教室時,就一定要指派一位從師範大學(NormalSchool)出來的老師。分別將三位老師指派3間教室。

5、每間教室的老師用在師範大學中的制式教學方法

3間教室指定老師使用師範大學的教學方式,去教自己專業科目的內容。

從上圖的程式執行結果來看,會發現教室可以接受不同的老師,但用一樣的方法教學,但教的是各自的內容。因此,之後教室要更換別的老師,或是有其他新增老師的變動,原教室和原即有的老師們的程式都不必做變動。會發現這樣的使用會更加的彈性,以及維護上需要調整的程式範圍較小,這就是Dependency Inversion Principle:依賴反轉。

--

--