橋接模式(Bridge Pattern)

  • 橋接模式概述

定義:將抽象部分與它的實現部分解耦,使得二者都可以獨立的變化編程

就拿咱們平常使用的蠟筆來講,蠟筆有不一樣的大小和顏色,因此咱們每每買的蠟筆盒中會有很多的蠟筆。須要用哪一個就用哪一個,是否是很方便???然而毛筆卻不是這樣,毛筆分爲不一樣大小,卻只有一個調色盤,裏面裝着不一樣的顏料。咱們須要什麼用到什麼,就用對應大小的毛筆去蘸對應的顏料。兩者想比,哪一個更方便呢??我卻是以爲仍是蠟筆方便,可是,試想一下,若是咱們筆的大小變化有不少,顏色我也要越多越好,以應對變化。那麼,咱們的蠟筆可能就會多到不可思議,而毛筆只要提供對對應大小的毛筆,顏色只要放到調色盤裏就OK了。這樣,咱們只要帶着筆和調色盤就行了,這比帶着許多隻蠟筆可要方便多了吧。橋接模式,就是要像毛筆這樣應對不一樣(多維度)變化而來的。ide

橋接模式是一種對象結構性模式,又被稱爲柄體(Handle and Body)模式接口(Interface)模式this

  • 橋接模式的結構

  

  1. Abstraction(抽象類):定義抽象類的接口,一般是抽象類而不是接口,其中定義Implementor(實現類接口)類型的對象並維護該對象,與Implementor之間是關聯關係
  2. RefinedAbstraction(擴展抽象類):擴充Abstraction定義的接口,實現了在Abstraction中聲明的抽象業務方法,在RefinedAbstraction中調用在Implementor中定義的方法
  3. Implementor(實現類接口):定義實現類的接口,僅提供基本操做,在子類中具體實現。並經過關聯關係,在Abstraction中不只調用本身的方法,也能夠調用Implementot的方法
  4. ConcreteImplementor(具體實現類):具體實現Implementor接口,在不一樣的子類中提供基本操做的不一樣實現
  5. 接口類:
    1 interface Implementor
    2 {
    3     void OperationImpl();
    4 }
  6. ConcreteImplementor類:
    1 class ConcreteImplementor:Implementor
    2 {
    3     public void OperationImpl()
    4     {
    5         //Specific Business Realization
    6     }
    7 }
  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 }
  8. RefinedAbstraction類:
    1 class RefinedAbstraction  : Abstraction
    2 {
    3     public override void Operation()
    4     {
    5         //Business methods
    6         impl.OperationImpl();
    7         //Business methods
    8     }
    9 }

上述圖可能不那麼容易理解,咱們看下毛筆的結構示意圖:spa

大小和顏色是兩個維度,因此毛筆類爲抽象類,在Brush類中聲明並部分實現毛筆的業務方法,而將各類型號的毛筆做爲其子類;顏色與毛筆存在「設置顏色」的關係,因此提供一個顏色接口,而將具體的顏色做爲接口的子類。這樣,型號的擴展和顏色擴展便可獨立,兩者又是關聯的,方便擴展設計

注意:color設爲protected是爲了只讓本身的子類纔可使用3d

應用實例code


 空客(Airbus)、播音(Boeing)和麥道(McDonnell-Douglas)都是飛機制造商,他們都生產載客飛機(Passenger Plane)和載貨飛機(Cargo Plane)。設計一個系統,實現他們對象

分析:飛機制造商是一個變化點,咱們能夠定義一個Plane抽象類,它的子類就是各類飛機制造商,類中有抽象Create方法,再定義一個KindofPlane接口,它有CreatePlane的方法,不一樣類型的飛機種類實現接口方法,這是第二個變化點,Plane和接口關聯,橋接起來。blog

結構:繼承

 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
  • 橋接模式的優勢

  1. 分離抽象接口及其實現部分,從而能夠得到更多維度組合對象。便可以搭建不少的橋
  2. 橋接模式可取代多層繼承方案,極大減小了子類的個數
  3. 提升了系統的可擴展性,多維度間任意擴展須要擴展的一個維度,不需修改原有系統,符合開閉原則
  • 橋接模式的缺點

  1. 會增長系統的理解與設計難度,須要對抽象層進行編程
  2. 要正確的分別出獨立變化的維度,使其使用範圍有必定侷限性
  • 橋接模式的適用環境 

  1. 若是一個系統須要在抽象化和具體化之間增長更多的靈活性,避免在兩個層次間創建靜態的繼承關係,能夠用橋接模式在抽象層創建關聯關係
  2. 抽象部分和實現部分能夠以繼承的方式獨立擴展而不互相影響,系統須要對抽象化角色和實現化角色進行動態耦合
  3. 一個類存在兩個或多個獨立變化的維度,且各自須要獨立的進行擴展
  4. 對於不但願使用繼承或由於多層繼承致使系統類的個數急劇增長的系統,橋接模式很適用
相關文章
相關標籤/搜索