橋接模式概述 定義:將抽象部分與它的實現部分解耦,使得兩者都能夠獨立的變化 就拿我們日常使用的蠟筆來說,蠟筆有不同的大小和顏色,所以我們往往買的蠟筆盒中會有不少的蠟筆。需要用哪個就用哪個,是不是很方便???然而毛筆卻不是這樣,毛筆分為不同大小,卻只有一個調色盤,裡面裝著不同的顏料。我們需要什麼用到什 ...
- 橋接模式概述
定義:將抽象部分與它的實現部分解耦,使得兩者都能夠獨立的變化
就拿我們日常使用的蠟筆來說,蠟筆有不同的大小和顏色,所以我們往往買的蠟筆盒中會有不少的蠟筆。需要用哪個就用哪個,是不是很方便???然而毛筆卻不是這樣,毛筆分為不同大小,卻只有一個調色盤,裡面裝著不同的顏料。我們需要什麼用到什麼,就用對應大小的毛筆去蘸對應的顏料。二者想比,哪個更方便呢??我倒是覺得還是蠟筆方便,但是,試想一下,如果我們筆的大小變化有很多,顏色我也要越多越好,以應對變化。那麼,我們的蠟筆可能就會多到難以想象,而毛筆只要提供對對應大小的毛筆,顏色只要放到調色盤裡就OK了。這樣,我們只要帶著筆和調色盤就好了,這比帶著許多只蠟筆可要方便多了吧。橋接模式,就是要像毛筆這樣應對不同(多維度)變化而來的。
橋接模式是一種對象結構性模式,又被稱為柄體(Handle and Body)模式或介面(Interface)模式。
- 橋接模式的結構
- Abstraction(抽象類):定義抽象類的介面,通常是抽象類而不是介面,其中定義Implementor(實現類介面)類型的對象並維護該對象,與Implementor之間是關聯關係
- RefinedAbstraction(擴展抽象類):擴充Abstraction定義的介面,實現了在Abstraction中聲明的抽象業務方法,在RefinedAbstraction中調用在Implementor中定義的方法
- Implementor(實現類介面):定義實現類的介面,僅提供基本操作,在子類中具體實現。並通過關聯關係,在Abstraction中不僅調用自己的方法,也可以調用Implementot的方法
- ConcreteImplementor(具體實現類):具體實現Implementor介面,在不同的子類中提供基本操作的不同實現
- 介面類:
1 interface Implementor 2 { 3 void OperationImpl(); 4 }
- ConcreteImplementor類:
1 class ConcreteImplementor:Implementor 2 { 3 public void OperationImpl() 4 { 5 //Specific Business Realization 6 } 7 }
- Abstraction類:
1 abstract class Abstraction 2 { 3 protected Implementor impl; 4 public void SetImpl(Implementor impl) 5 { 6 this.impl = impl; 7 } 8 9 public abstract void Operation(); 10 }
- RefinedAbstraction類:
1 class RefinedAbstraction : Abstraction 2 { 3 public override void Operation() 4 { 5 //Business methods 6 impl.OperationImpl(); 7 //Business methods 8 } 9 }
上述圖可能不那麼容易理解,我們看下毛筆的結構示意圖:
大小和顏色是兩個維度,所以毛筆類為抽象類,在Brush類中聲明並部分實現毛筆的業務方法,而將各種型號的毛筆作為其子類;顏色與毛筆存在“設置顏色”的關係,所以提供一個顏色介面,而將具體的顏色作為介面的子類。這樣,型號的擴展和顏色擴展即可獨立,二者又是關聯的,方便擴展
註意:color設為protected是為了只讓自己的子類才可以使用
應用實例
空客(Airbus)、播音(Boeing)和麥道(McDonnell-Douglas)都是飛機製造商,他們都生產載客飛機(Passenger Plane)和載貨飛機(Cargo Plane)。設計一個系統,實現他們
分析:飛機製造商是一個變化點,我們可以定義一個Plane抽象類,它的子類就是各種飛機製造商,類中有抽象Create方法,再定義一個KindofPlane介面,它有CreatePlane的方法,不同類型的飛機種類實現介面方法,這是第二個變化點,Plane和介面關聯,橋接起來。
結構:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace BridgePattern 7 { 8 interface KindofPlane//Implementor 9 { 10 void CreatePlane(); 11 } 12 class PassengerPlane : KindofPlane//ConcreteImplementorA 13 { 14 15 public void CreatePlane() 16 { 17 Console.WriteLine("Create Passenger Plane"); 18 } 19 } 20 class CargoPlane : KindofPlane//ConcreteImplementorB 21 { 22 23 public void CreatePlane() 24 { 25 Console.WriteLine("Create Cargo Plane"); 26 } 27 } 28 abstract class Plane//Abstraction 29 { 30 protected KindofPlane planekind; 31 public void setkind(KindofPlane planekind) 32 { 33 this.planekind = planekind; 34 } 35 public abstract void Create(); 36 37 } 38 class Airbus : Plane//RefinedAbstraction 39 { 40 public override void Create() 41 { 42 Console.WriteLine("Airbus:"); 43 planekind.CreatePlane(); 44 } 45 } 46 class Boeing : Plane//RefinedAbstraction 47 { 48 public override void Create() 49 { 50 Console.WriteLine("Boeing:"); 51 planekind.CreatePlane(); 52 } 53 } 54 class McDonnell_Douglas : Plane//RefinedAbstraction 55 { 56 public override void Create() 57 { 58 Console.WriteLine("McDonnell_Douglas:"); 59 planekind.CreatePlane(); 60 } 61 } 62 class Program 63 { 64 static void Main(string[] args) 65 { 66 Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 67 KindofPlane passengerPlane = new PassengerPlane(); 68 Airbus air = new Airbus(); 69 air.setkind(passengerPlane); 70 air.Create(); 71 Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 72 KindofPlane cargoPlane = new CargoPlane(); 73 Boeing boe = new Boeing(); 74 boe.setkind(cargoPlane); 75 boe.Create(); 76 Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 77 KindofPlane cargpPlane2 = new CargoPlane(); 78 McDonnell_Douglas mc= new McDonnell_Douglas(); 79 mc.setkind(cargoPlane); 80 mc.Create(); 81 Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 82 } 83 } 84 }View Code
- 橋接模式的優點
- 分離抽象介面及其實現部分,從而可以獲得更多維度組合對象。即可以搭建很多的橋
- 橋接模式可取代多層繼承方案,極大減少了子類的個數
- 提高了系統的可擴展性,多維度間任意擴展需要擴展的一個維度,不需修改原有系統,符合開閉原則
- 橋接模式的缺點
- 會增加系統的理解與設計難度,需要對抽象層進行編程
- 要正確的分別出獨立變化的維度,使其使用範圍有一定局限性
- 橋接模式的適用環境
- 如果一個系統需要在抽象化和具體化之間增加更多的靈活性,避免在兩個層次間建立靜態的繼承關係,可以用橋接模式在抽象層建立關聯關係
- 抽象部分和實現部分可以以繼承的方式獨立擴展而不互相影響,系統需要對抽象化角色和實現化角色進行動態耦合
- 一個類存在兩個或多個獨立變化的維度,且各自需要獨立的進行擴展
- 對於不希望使用繼承或因為多層繼承導致系統類的個數急劇增加的系統,橋接模式很適用