無論是說話或是設計程式,都需要注意邏輯不能馬上定義得太明白,往後需要變更或是維護的時候才會比較方便。

定義

讓我們看一下原文的定義:

1
2
High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g. interfaces).
Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

翻譯蒟蒻

  1. 高階模組不可以依賴於低階模組,兩者必須依賴抽象概念上。
  2. 抽象不可以依賴細節上,而是反過來依賴抽象上。

看完之後,你可能還會覺得這在說什麼…
其實這個概念跟我們日常生活很像,你跟別人約定好的事情不能講太細節的事情
不然到時候有什麼狀況發生,其實很難去應變

日常舉例

今天如果老師跟你說:下次考試會考課本的第一章全部和第二章的第三小節
結果下次考試老師跟大家說:不好意思…我忘記把題目加在裡面了,今天就先只考第一章。

你說這是不是很討厭!?明明說好要做的事情,為什麼明明說好要考第二章的第三小節
最後卻沒有考?

其實講話是要有藝術的,老師應該這樣說:下次考試會考課本的第一章全部和第二章某一小節
這樣講,學生不管拿到什麼考卷,大概也就認了,老師也不會被講閒話了。

例子

因此,設計程式也是有藝術的,如果你把高階模組依賴於低階模組,可能會導致整個組件有奇怪的地方。

1
2
3
4
5
6
7
8
const Person = () => {
...
const buySomeCoffee = async() => {
const coffee = await fetch('http://...');
setCoffee(coffee);
}
...
}

相依關係: Person -> buySomeCoffee

從這邊你會發現一件事情,人相依於買咖啡這件事情,但是並不是每個人都一定會買咖啡對吧?
因此這邊需要反轉一下相依性。

1
2
3
4
5
6
7
const Person = ({ buySomeCoffee }) => {
...
useEffect(() => {
buySomeCoffee();
},[]);
...
}

相依關係: Person -> (buySomeCoffee) -> 執行buySomeCoffee
如此一來,耦合性就降低得不少
buySomeCoffee的更動,也跟Person沒有太大的關係