電腦運算和系統設計中,鬆耦合的系統是指:

  1. 組件之間的關聯性不強(彼此之間的關係可以切斷),若有鬆耦合的話,會使得一個組件的變更對其他組件的影響降到最低。
  2. 每一個組件對其他獨立組件的定義所知甚少或一無所知。子範圍包括類、接口、數據和服務之間的耦合[1]

鬆耦合是緊耦合的對立面。

優點和缺點

編輯

鬆耦合系統中的組件可以用提供相同服務的替代實現所替換。鬆耦合系統中的組件比較不會限制使用相同平台、相同語言、相同操作系統或相同構建環境。

如果系統在時間上是解耦的,那麼也很難提供事務完整性(transactional integrity);需要額外的協調協議。跨系統數據複製英語Replication (computing)滿足了鬆耦合性(可用性),但是在維護一致性英語Data_consistency數據同步)上會出現問題。

集成

編輯

鬆耦合在更廣泛的分布式系統設計中是透過使用事務,面向消息中間件英語Message-oriented_middleware提供的隊列和互操作性標準來達成的。[2]

促進鬆耦合的四類自主性是:引用自主性,時間自主性,格式自主性和平台自主性。[3]

鬆耦合是一種架構原則,設計目標是面向服務架構;以下列出了鬆耦合和對應的緊耦合的11種形式:[4]

  • 透過中介的物理連接,
  • 異步通信方式,
  • 只在數據模型中的簡單常見類型,
  • 弱類型系統,
  • 以數據為中心並且自包含的消息,
  • 過程邏輯的分布式控制,
  • (服務的消費者和提供者的)動態綁定英語Dynamic binding (computing)
  • 平台獨立性,
  • 業務級補償而不是系統級的事務,
  • 不同的時間的部署,
  • 版本中的隱式升級。

企業服務總線(Enterprise Service Bus,ESB)中間件誕生在實現鬆散耦合的多個維度;然而,過於機械化和錯誤安置的ESB還可以產生相反的效果,產生非預期的緊耦合和中心架構熱點。[5]

事件驅動架構英語Event-driven architecture也旨在促進鬆散耦合。[6]

降低耦合的方法

編輯

接口的鬆耦合可以透過發布標準格式的數據(如XMLJSON)來增強。

程序組件之間的鬆耦合可以透過使用標準數據類型參數來增強。傳遞自定義數據類型或對象需要組件雙方了解自定義數據的定義。

服務的鬆耦合可以透過減少給服務傳入的關鍵數據的信息來增強。例如,當只有客戶標識傳入並且客戶地址在服務內獲取,服務發送一個字母是最可重用的。這將解耦服務,因為服務不需要按特定的順序調用(如:GetCustomerAddress,SendLetter)

編程

編輯

耦合是指一個組件直接了解其他組件的程度。運算中的鬆耦合解釋為封裝與無封裝。

緊耦合的一個例子發生在依賴類直接包含一個提供所需行為的具體類的指針。在不改變依賴類的情況下,無法替換依賴,或改變「簽名」。鬆耦合發生在依賴類只包含接口的指針,接口可以由一個或多個具體類實現。依賴類只依賴接口指定的「契約」:實現類必須提供的方法和/或屬性的定義列表。任何實現了接口的類就可以滿足依賴類的依賴而無需修改類。這使得軟件設計具有可擴展性;無需改變依賴類,可以編寫一個新類實現接口來取代當前的依賴在部分或全部的情況下;新老類可以自由交換。強耦合不允許這樣做。

這個UML圖說明依賴類和一組提供所需行為的具體類之間的鬆耦合的例子:

 

相比之下,這個圖表顯示了強的替代設計相關類之間的耦合和提供者:

 

鬆耦合的其他形式

編輯

擁有作為核心模塊的函數(參見函數式編程)或函數對象的計算機編程語言提供了鬆耦合編程的極好的例子。函數式語言擁有續體閉包或生成器等模式。函數式編程語言的例子參見ClojureLispSmalltalkRuby等面向對象的語言擁有代碼塊,而Eiffel擁有agent。基本思想是具象化(封裝為對象)獨立於任何其他封閉概念的函數(例如將對象函數與封閉對象的任何直接知識解耦)。作為頭等函數的一種形式,函數作為對象的更進一步知識參見頭等函數

例如,在面向對象的語言中,當對象的一個函數被引用為一個對象(無需了解包含他的宿主對象)時,新的函數對象可以傳遞,存儲,稍後調用。(功能對象交給的)接收對象可以在自己方便的時候安全地執行(調用)所包含的函數,無需了解包含他的宿主對象。透過這種方式,一個程序可以執行功能對象的鏈或組,而安全地脫離擁有任何包含他們的宿主對象的直接引用。

電話號碼是一個極好的類比,很容易說明這種分離的程度。

例如:一些實體為他人提供電話號碼來完成一個特定的工作。當號碼被呼叫時,呼叫者實體實際上說,「請幫我做這項工作。」解耦或鬆耦合是顯而易見的。拿到號碼的實體呼叫時可能並不了解號碼從哪兒來的(例如號碼提供者的引用)。另一方面,呼叫者和被呼叫者之間解耦了,無需知道他們是誰,他們在哪裡,呼叫接收者內部是如何操作的。

將例子更進一步,呼叫者可能會對接收者說「請為我做這個工作。幹完了用這個號碼打電話回復我。」提供給接收者的「號碼」稱為「回調」。同樣,這個函數對象的鬆耦合或分離性質是明顯的。回調的接收者不知道調用的是誰。只知道它可以調用,並決定何時調用。在現實中,回調的可能都不是最初的提供者。這種級別的間接使函數對象成為實現鬆耦合程序的一個優秀技術。

衡量數據元素耦合

編輯

鬆耦合的程度可以透過記錄發送或接收系統中可能發生的數據元素的變化數量來度量,並確定計算機是否仍然能夠正確地進行通信。這些變化包括的項目如:

  1. 添加新的數據元素到消息
  2. 改變數據元素的順序
  3. 改變數據元素的名稱
  4. 改變數據元素的結構
  5. 省略數據元素

參閱

編輯

參考資料

編輯
  1. ^ Loosely Coupled: The Missing Pieces of Web Services by Doug Kaye
  2. ^ Pautasso C., Wilde E., Why is the Web Loosely Coupled?頁面存檔備份,存於網際網路檔案館), Proc. of WWW 2009
  3. ^ F. Leymann Loose Coupling and Architectural Implications頁面存檔備份,存於網際網路檔案館), ESOCC 2016 keynote
  4. ^ N. Josuttis, SOA in Practice. O'Reilly, 2007, ISBN 978-0-596-52955-0.
  5. ^ M. Keen et al, Patterns: Implementing an SOA using an Enterprise Service Bus頁面存檔備份,存於網際網路檔案館), IBM, 2004
  6. ^ How EDA extends SOA and why it is important頁面存檔備份,存於網際網路檔案館) Jack van Hoof