桥接模式(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. 对于不但愿使用继承或由于多层继承致使系统类的个数急剧增长的系统,桥接模式很适用
相关文章
相关标签/搜索