[OOD] 隔離變化-橋接模式

Horky發表於2015-04-21

背景

正如電腦主機和顯示器之間,主機的配置千變萬化,不斷升級,顯示器可能升級緩慢。如果這時你買的是一體機,硬體升級就要受到限制。這就是一個典型的分離變化的需求場景。

在應用中,一個業務會有多個協作者,直接耦合會導致其中一個類的變化就會影響其它類的行為。這時最好的做法是對行為進行抽象,區分出變與不變,或者核心與外圍的部分,然後定義出介面來隔離變化。

以Chromium的主文件載入為例。FrameLoader負責一個Frame的載入邏輯,從開始載入(load())或者重新載入(reload()),到結束(stopLoading()),這個過程是固定的,概括而言(即進行抽象)就是:
 開始 -> 傳送請求 -> 收到響應頭資訊 -> 收到頁面資料 -> 完成。

但是中間過程中每個階段可能做的事情不一樣 (識別變化),包括:
  1. 請求傳送前,做些準備工作,或者改變一些引數。
  2. 收到響應頭,判斷一下響應頭裡如果有特殊欄位,需要採取不同的行為。
等等。

一邊是Frame和FrameLoader的互動,另一邊則是FrameLoader與業務層的互動。這就是需要進行隔離的介面。

設計方案


Frame和FrameLoader仍然關注於載入的邏輯,需要外部的協作時通過FrameLoaderClient這個介面與具體的實現互動。外部的FrameLoaderClientImpl執行如何的操作時也完全由它們控制,比如FrameLoaderClientImpl,有些事則進一步交由再上層的模組去完成。

這種方案被大量使用,比如WebViewClient和WebWidget:
          
這個示例更接近於它所屬的橋接(Bridge)模式, 而上面FrameLoaderClient則像是一個退化的版本。

小結

這種模式就是橋接模式(Bridge Pattern)。

核心都是使用一個抽象的介面隔離變化,既提高了各層的內聚性,又降低它們間的耦合。符合OO原則中的:
  1. 封裝變化
  2. 針對介面程式設計,而不針對具體的實現。
  3. 降低互動物件的耦合度。

缺點是: 提高了複雜度。

相關文章