耦合與系統設計
Strong or loose, we live in dread,
Of the coupling monster under the bed.
Yet without it, your system would flake,
Coupling is a pillar you can’t forsake.
耦合是一切罪惡的根源?
:「這邊的 code 一團亂,有複雜的相依關係。」
:「程式碼到底是誰寫的?」
git blame 下去,發現是半年前的自己…
一個完全沒有耦合的系統
所有元件都彼此獨立、可替換
寫起來很舒服
想怎麼改就怎麼改
但這是好設計嗎?
能滿足商業需求嗎?
什麼是耦合?
詞源
Coupling 源自拉丁文 copulare:
co:一起
apere:連結、固定
意為「將事物連結在一起」。
在生物學,copulare 則為「交配」的意思。
1 | ∧ _ ∧ ∧_∧ |
服務間存在耦合 = 服務間存在連結
手錶內有無數的齒輪與彈簧相互連結
引擎、車輪、剎車和其他零件耦合在一起成汽車
不同的耦合設計,帶來不同的結果及維護成本
我們根據什麼因素決定耦合的強與弱呢?
耦合程度
耦合程度越大,它們需要同時修改的頻率就越高
什麼原因導致這些元件需要一起改變?
- 共享的生命週期
- 共享的知識
共享的生命週期
A. 單體式應用程式
1 | ┌─────────────────────────────┐ |
B. 獨立的模組
1 | ┌──────────────┐ ┌──────────────┐ |
共享的知識
元件為了能夠協同合作,必須共享知識
共享知識可以用幾種不同的方式存在:
- 知曉模組的介面
- 知悉對方的需求
- 獲知對方的實作細節
在耦合元件的邊界,共享越多的知識,
你會遭遇的連鎖變動就越多。
A. 直接依賴具體實作
1 | ┌──────────────┐ |
B. 依賴介面,但暴露實作細節
1 | ┌──────────────┐ |
C. 依賴抽象介面
1 | ┌──────────────┐ |
知識的流動方向
1 | ┌───────┐ ┌───────┐ |
Upstream and Downstream Component
Upstream Component(上游元件)
- 介面會公開知識,描述其功能及如何整合
- 知識的提供者
Downstream Component(下游元件)
- 使用上游元件的功能
- 知識的接收者
1 | ┌───────┐ ┌───────┐ |
系統
《系統思考》:系統為一組相互連結的元素,其組織方式能夠達成某種目的。
系統的三個核心要素
- 元件 (component)
- 連結關係 (interconnection)
- 目的 (purpose)
軟體階層
- 類別本身也能視為系統,其元件包含方法和變數
- 方法本身也是系統,由個別的程式描述來共同實現方法的目的
系統中的耦合
系統核心三元素
- 目的需要元件和連結關係
- 元件和連結關係實現目的
- 元件允許連結關係
- 連結關係指揮元件
系統的改變
在任何系統中,你不可能只改變其中一個元素,但不影響到另外兩個。
這帶出了系統設計的重要概念: 邊界 (boundaries) 。
系統設計的本質
便是關於邊界的取捨。
(裡外有什麼、有哪些會跨過邊界或來回移動)
耦合
人們經常假設軟體設計要徹底去耦合,使元件完全獨立,但實際上並非如此。
若兩個元件要協作,它們就得共享知識。
軟體工程師的工作
我們必須留意元件的連結關係,即元件間分享了哪些知識,
用什麼方式分享的,這些知識分享又會如何影響系統。
References
ʕ •ᴥ•ʔ: Thank you