Dependency inversion principle
依賴倒置原則(Dependency inversion principle
)有兩個主要部分:
- 高層模組不應該依賴於低層模組。兩者都應該依賴於抽象。
- 抽象不應該依賴於具體實現。具體實現應該依賴於抽象。
在軟體設計中,如果一個類(class
)使用了另一個類稱為依賴(dependency
或 coupling
),每增加一點依賴,就會增加一些風險,因為當某個類A知道了另一個類B的內容太多的話(稱為高度耦合high degree of coupling
),當B更改的話,那麼A也會需要大量的修改,這樣很容易產生錯誤。
在設計中,有些類是high-level的,而有些類是low-level的,high-level的類會依靠low-level的類去完成某些工作。我們在設計時,要考慮依賴倒置原則,減少一些耦合度。
如果要建立一個遊戲,其中角色可以探索房間,並使用開關(switch)將門(dor)打開,在實作時,你可能會想到要建立一個Switch類與一個Door類,其中
- Switch屬於high-level的類,它負責判斷角色是否移動到對應的位置,並是否觸發對應的行為
- Door屬於low-level的類,它負責開關門的實際操作邏輯
如果沒有使用依賴倒置原則的話,可能會如下實作
- Switch依賴於Door,當條件觸發時,呼叫door去開門
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32public class Switch
{
public Door door;
public bool isActivated;
public void Toggle()
{
if (isActivated)
{
isActivated = false;
door.Close();
}
else
{
isActivated = true;
door.Open();
}
}
}
public class Door
{
public void Open()
{
Debug.Log("The door is open.");
}
public void Close()
{
Debug.Log("The door is closed.");
}
}
這樣的實作沒有問題,但是如果開關(Switch)不只是開門,還可能會觸發一些陷阱的話,就不得不去修改Switch類,這樣違反了開閉原則(Open-closed principle)
你可以將開關這個動作抽象=>ISwitchable。
1 | public interface ISwitchable |
讓Door去實作這個抽象ISwitchable
1 | public class Door : MonoBehaviour, ISwitchable |
而Switch則依賴這個抽象ISwitchable
1 | public class Switch : MonoBehaviour |
透過這種方式將上層對底層的依賴剝離至抽象,讓上層可以不需更改程式碼,只需傳入不同的ISwitch實作便可以做到開關不同的物件。