参考文献

桥接模式

  • Bridge的意思是"桥梁".桥梁的功能是将河流的两侧连接起来一样,Bridge模式作用也是将两样东西连接起来,它们分别是类的功能层次结构类的实现层次结构.

类的功能层次结构

  • 希望增加新功能时,假设现在有一个类Something.当我们想在Something中增加新功能(想增加一个具体方法时),会编写一个Something类的子类(派生类),即SomethingGood类.这样就构成了一个小小的类层次结构.

    1
    2
    Something
    |- SomethingGood
    • 这就是为了增加新功能而产生的层次结构
      • 父类具有基本功能
      • 在子类中增加新的功能
  • 以上这种层次结构被称为"类的功能层次结构"

类的实现层次结构

  • 希望增加新的实现时,抽象类声明了一些抽象方法,定义了接口(API),然后子类负责去实现这些抽象方法.父类的任务是通过声明抽象方法的方式定义接口(API),而子类的任务是实现抽象方法.

  • 这里其实也存在层次结构,例如当子类ConcreteClass实现了父类AbstractClass类的抽象方法时,它们之间就构成了一个小小的层次结构.

    1
    2
    AbstractClass
    |- ConcreteClass
    • 父类通过声明抽象方法来定义接口(API)
    • 子类通过实现具体方法来实现接口(API)
  • 这种层次结构被称为"类的实现层次结构"

组件

  • 抽象化(Abstraction):定义抽象部分的接口,并维护一个指向实现部分对象的引用.

    • 该角色位于"类的功能层次结构"的最上层.它使用Implementor角色的方法定义了基本的功能.
  • 具体实现化(Implementor):定义实现部分的接口.

    • 该角色位于"类的实现层次结构"的最上层.它定义了用于实现Abstraction角色的接口(API)的方法
  • 抽象实现化(Refined Abstraction):扩展抽象部分的接口,通常使用抽象部分中的方法来完成更多功能.

  • 具体实现(Concrete Implementor):实现具体实现化角色的接口.

实现方式

  • 定义抽象部分的接口(抽象化Abstraction)

    1
    2
    3
    4
    // 抽象化接口
    interface Payment {
    void pay();
    }
  • 定义实现部分的接口(具体实现化Implementor)

    1
    2
    3
    4
    // 实现化接口
    interface PaymentMethod {
    void processPayment();
    }
  • 创建具体实现部分的类,实现实现部分的接口(Concrete Implementor)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 具体实现化类
    class Alipay implements PaymentMethod {
    public void processPayment() {
    System.out.println("使用支付宝完成支付");
    }
    }

    class WeChatPay implements PaymentMethod {
    public void processPayment() {
    System.out.println("使用微信支付完成支付");
    }
    }
  • 在抽象部分中维护对实现部分的引用(Refined Abstraction)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 抽象实现化类
    abstract class Order implements Payment {
    protected PaymentMethod paymentMethod;

    protected Order(PaymentMethod paymentMethod) {
    this.paymentMethod = paymentMethod;
    }

    public abstract void pay();
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // 具体实现类
    class NormalOrder extends Order {
    public NormalOrder(PaymentMethod paymentMethod) {
    super(paymentMethod);
    }

    public void pay() {
    System.out.print("普通订单:");
    paymentMethod.processPayment();
    }
    }

    class DiscountOrder extends Order {
    public DiscountOrder(PaymentMethod paymentMethod) {
    super(paymentMethod);
    }

    public void pay() {
    System.out.print("优惠订单:");
    paymentMethod.processPayment();
    }
    }
  • 创建抽象实现化角色的类,扩展抽象部分的接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class Main {
    public static void main(String[] args) {
    PaymentMethod alipay = new Alipay();
    Order normalOrder = new NormalOrder(alipay);
    normalOrder.pay();
    // 输出:普通订单:使用支付宝完成支付

    PaymentMethod weChatPay = new WeChatPay();
    Order discountOrder = new DiscountOrder(weChatPay);
    discountOrder.pay();
    // 输出:优惠订单:使用微信支付完成支付
    }
    }

使用场景

  • 想避免在抽象和其实现之间存在永久绑定.例如,当实现在运行时必须被选择或切换时,就会出现这种情况.
  • 抽象和它们的实现都应该通过子类化来进行扩展.在这种情况下,桥接模式使您能够组合不同的抽象和实现,并且可以独立地对它们进行扩展.
  • 对抽象的实现进行更改不应该影响客户端,也就是说,客户端的代码不需要重新编译.

好处

  • Bridge模式的特征是将"类的功能层次结构"与"类的实现层次结构"分离开了.将类的这两个层次结构分离开有利于独立地对它们进行扩展.
    • 当想要增加功能时,只需要在"类的功能层次结构"一侧增加类即可,不必对"类的实现层次结构"做任何修改.而且,增加后的功能可以被"所有的实现"使用.