
早在耦合變成世界各地軟體工程師的宿敵的很久之前,耦合就已經存在了。這個詞源自拉丁文copulare,而該詞又源自co(一起)和apere(綁緊)。因此耦合的意思就是「綁在一起」,或者把東西連接起來。
當你看到「耦合」這個詞,你可以把它換成「連結」。當你說兩個服務之間存在「耦合」, 就跟說這兩個服務之間存在「連結」是一樣的。同樣的,若說一個物件跟一個資料庫有高度耦合,就等於說這個物件和資料庫有高度連結。
這顯示耦合是一種無所不在的現象,到處都能觀察到耦合:只要兩個個體相互連接,那麼它們之間就存在耦合。時鐘裡面有無數齒輪和彈簧相互連結,以便能正確衡量時間。引擎、車軸、車輪、剎車和其他零件耦合在一塊構成汽車。器官耦合起來構成生命體,包括我們人類。在更小的層面上,粒子的互動構成我們宇宙中的萬物,而在更大的層面上,星體則會透過重力場互動─ 儘管隔著極遠的距離,星體之間仍然存在耦合。
耦合暗示了相連結個體之間的關係,而相耦合的東西便能用某種方式影響彼此。話雖如此,世上有各式各樣的系統和設計它們的各種方式,也有連接元件的不同辦法。不同的設計會帶來不同的結果與維護成本。
耦合與系統設計
若要了解耦合在系統中扮演的角色,我們就務必先定義何謂系統。Donella H. Meadows 在她的經典作品《系統思考》(Thinking in Systems: A Primer)中,將系統定義為一組相互連結的元素,其組織方式能夠達成某種目的。這個簡潔的定義描述了構成系統的三個核心要素:元件(component)、連結關係(interconnection),以及目的(purpose)。
在軟體工程中不只有眾多不同類型的系統,就連軟體本身都能解讀成由相互連結的小系統所構成的大系統。我們在更高層級能看到服務、應用程式、排程工作、資料庫與其他元件,它們會耦合起來實現系統的整體目的,也就是其商業功能。但這些大型元件本身自成一個系統,只不過層級較低而已。比如,圖1.5 中的「處理」服務是用物件導向程式語言寫的,因此該服務是由一系列所需的類別組成,好實作出該服務的功能。這些類別是該服務的元件,實現了整體系統(服務)的功能。
圖1.5 典型軟體系統的元素。
甚至,你能進一步鑽研軟體系統的階層本質:這些類別本身同樣能被視為系統,其元件包括方法和變數,用來建置出該類別的功能。再往下,方法自身也是系統,由各別的程式敘述來共同實現該方法的目的。
那麼,是什麼讓各種層級的元件能夠協同合作、達成整體系統的目的呢?互動。
系統中的耦合
齒輪是真實鐘錶系統的元件。鐘錶系統的目的是衡量和顯示時間,但光是只有必要的齒輪跟彈簧是不夠的。系統若要能發揮作用,其元件就必須相連─ 或者產生耦合─ 以便能協同合作。話雖如此,把它們任意組合起來是沒用的。元件必須照特定方式結合,才能實現系統的目標。耦合不只能維繫整個系統的結構,更能讓系統價值超越個別零件價值的總和。
系統三大元素─ 元件、互動和目的─ 彼此密切相關:
● 一個系統的目的需要一群特定的元件,透過元件之間的互動來達成。
● 元件介面的設計能允許和禁止某些整合行為。此外,元件自身的功能能夠令系統實現其目的。
● 互動關係讓系統能藉由指揮元件協作來達成目的。
總歸來說,在任何系統裡面,你不可能只改變其中一個元素,但不影響到至少另外一兩個元素。舉例來說,你想把一個軟體系統的功能(或者其目的)加以延伸,而若要改變目的,就必須修改其元件─ 服務、模組跟其他需要演進來適應新需求的部分。甚至,修改元件可能會改變其互動方式,或者改變元件整合和相互溝通的方式。
這帶出了系統設計的另一個重要概念:邊界(boundaries)。如Ruth Malan 所說:「系統設計的本質便是關於邊界(裡外有什麼、有哪些會跨過邊界或來回移動)以及其取捨。它重新定義哪些東西屬於外界,正如它定義了哪些該留在邊界內」(Malan,2019)。一個元件的邊界定義了哪些知識屬於元件,哪些知識又該留在外頭─ 比如,哪些功能該由這個元件實作,哪些責任又該交給系統的其他部分。甚至,邊界定義了一個元件該如何跟系統的其他部分互動,或者更精確來說,有哪些知識允許通過元件邊界。到最後,元件與互動定義了系統設計能夠達成什麼結果。這表示互動性,也就是元件耦合的設計,是系統設計與生俱來的一環。
以一般的系統來說,耦合概念在系統設計是不可或缺的。人們經常假設軟體設計的目的是要徹底去耦合、使元件完全獨立,但實際上並非如此。你不可能把耦合降到零;若兩個元件應該要協作,它們之間就得共享知識;互動的前提就是要分享知識。元件若沒有互動或耦合,就不可能實現系統目的。正是單元之間的互動成就了系統。
我們身為軟體工程師,經常著重在把系統解耦合成元件的任務。為了做到這點,我們得先檢視商業領域,然後決定哪些部分可以打散成服務、模組跟物件。基本上,我們在設計系統架構時,經常會太過專注在劃定範圍上,但這些範圍之間的關聯最起碼也一樣重要─ 我們必須留意元件的互動設計,意即元件之間會分享哪些知識、知識如何共享,這些知識分享又會如何影響整體系統。此外,各位應該已經發現,元件的設計與元件間的互動其實息息相關。耦合不僅定義了哪些知識被允許在元件之間流動,更定義了哪些知識根本不該離開所屬元件的邊界。這表示在設計模組化軟體系統時,耦合其實是不可或缺的工具。
耦合是將系統維繫起來的黏著劑,那麼這是否表示隨意結合元素和相依性就能產生良好設計呢?當然不可能。耦合可以是必要的,也有可能是意外的副作用。模組化設計需要消除意外的耦合,並謹慎管理必要的相互關係。(本文摘錄整理自《軟體設計耦合的平衡之道》,博碩文化提供)
圖片來源/博碩文化
書名 軟體設計耦合的平衡之道:建構模組化軟體系統的通用設計原則(Balancing Coupling in Software Design)
Vlad Khononov/著;王寶翔(Alan Wang)/譯
博碩文化出版
定價:650元
作者簡介
Vlad Khononov
Vlad Khononov是一名擁有廣泛業界經驗的軟體工程師,替規模各異的公司做事,扮演的角色自網站管理員到首席架構師都有。他的主要專業包括軟體架構、分散式系統及領域驅動設計。身為顧問與訓練師,Vlad協助企業理解它們的商業領域、重新整頓老舊系統,並搞定複雜的架構挑戰。
熱門新聞
2025-07-07
2025-07-07
2025-07-08
2025-07-03
2025-07-07
2025-07-04
2025-07-07