Skip to content

桥接模式(Bridge Pattern)

桥接是一种结构型设计模式,可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构,从而能在开发时分别使用。

结构

image

  • 抽象部分 (Abstraction) 提供高层控制逻辑, 依赖于完成底层实际工作的实现对象。
  • 实现部分 (Implementation)为所有具体实现声明通用接口。抽象部分仅能通过在这里声明的方法与实现对象交互。
  • 具体实现 (Concrete Implementations) 中包括特定于平台的代码。
  • 精确抽象 (Refined Abstraction) 提供控制逻辑的变体。 与其父类一样, 它们通过通用实现接口与不同的实现进行交互。
  • 客户端 (Client) 仅关心如何与抽象部分合作。 但是, 客户端需要将抽象对象与一个实现对象连接起来。

介绍

假如你有一个几何 形状 Shape 类,从它能扩展出两个子类: 圆形 Circle 和 方形 Square 。 你希望对这样的类层次结构进行扩展以使其包含颜色, 所以你打算创建名为红色 Red 和 蓝色 Blue 的形状子类。但是,由于你已有两个子类,所以总共需要创建四个类才能覆盖所有组合,例如 蓝色圆形 BlueCircle 和 红色方形 RedSquare 。

qq截图20220405151908.png

在层次结构中新增形状和颜色将导致代码复杂程度指数增长。

例如添加三角形状,你需要新增两个子类,也就是每种颜色一个;此后新增一种新颜色需要新增三个子类,即每种形状一个。

解决方案

桥接模式通过将继承改为组合的方式来解决这个问题。具体来说,就是抽取其中一个维度并使之成为独立的类层次,这样就可以在初始类中引用这个新层次的对象,从而使得一个类不必拥有所有的状态和行为。

qq截图20220405152131.png

将一个类层次转化为多个相关的类层次,避免单个类层次的失控。

根据该方法,我们可以将颜色相关的代码抽取到拥有红色和蓝色两个子类的颜色类中,然后在形状类中添加一个指向某一颜色对象的引用成员变量。

现在,形状类可以将所有与颜色相关的工作委派给连入的颜色对象。这样的引用就成为了形状和颜色之间的桥梁。此后,新增颜色将不再需要修改形状的类层次,反之亦然。

适用环境

  • 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

  • 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。

  • 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

实现

ColorAPI:用于画各种颜色的接口

java
public interface Color {
    public void paint();
}

BlueColorAPI :画蓝色的实现类

java
public class BlueColor implements Color {
    @Override
    public void paint() {
        System.out.println("画上蓝色");
    }
}

RedColorAPI :画红色的实现类

java
public class RedColor implements Color
{
    @Override
    public void paint() {
        System.out.println("画上红色");
    }
}

Shape :抽象形状类

java
public abstract class Shape {
    protected Color Color;    //添加一个颜色的成员变量以调用ColorAPI 的方法来实现给不同的形状上色

    public void setDrawAPI(Color Color) {      //注入颜色成员变量
        this.Color= Color;
    }

    public abstract void draw();        
}

Circle :圆形类

java
public class Circle extends Shape {
    @Override
    public void draw() {
        System.out.print("我是圆形");
        Color.paint();
    }
}

Rectangle :长方形类

java
public class Rectangle extends Shape {
    @Override
    public void draw() {
        System.out.print("我是长方形");
        Color.paint();
    }
}

Client:客户端

java
public class Client {

    public static void main(String[] args) {
        //创建一个圆形
        Shape shape = new Circle();
        //给圆形蓝色的颜料
        shape.setDrawAPI(new BlueColor());
        //上色
        shape.draw();

        //创建一个长方形
        Shape shape1 = new Rectangle();
        //给长方形红色的颜料
        shape1.setDrawAPI(new RedColor());
        //上色
        shape1.draw();

    }
}

假如现在客户让我们增了一个三角形,我们只需要新增一个三角形类就可以了

java
public class Triangle extends Shape {
    @Override
    public void draw() {
        System.out.println("我是三角形");
        colorAPI.paint();
    }
}

增加颜色也是一样,我们只需要增加一个新的颜色并实现ColorAPI的接口即可,而无需更改类的层次

java
public class YellowColor implements Color {
    @Override
    public void paint() {
        System.out.println("画上黄色");
    }
}