桥接模式(Bridge Pattern)

原文地址:https://jaune162.blog/design-pattern/bridge-pattern.html

更多精彩文章请移步:https://jaune162.blog

更多专题系列文章请移步:https://books.jaune162.blog

序言

桥接模式是一种结构型设计模式,它旨在将抽象部分与实现部分分离,从而使它们可以独立地变化。这种模式通过使用组合而不是继承的方式,可以在抽象和实现之间建立一座桥梁,使得它们可以独立地变化而互不影响。

在桥接模式中,抽象部分包含一个指向实现部分的引用,而实现部分则包含一个指向抽象部分的引用。这种结构使得抽象部分和实现部分可以各自独立地进行扩展和变化,而不会相互影响。

定义

Decouple an abstraction from its implementation so that the two can vary independently.

将抽象与其实现分离,以便二者可以独立变化。

结构

考虑这样一个问题,有一个画图的需求,这个图形有形状和颜色两种属性。起初只有红色正方形,于是定义了一个 RedSquare的类,然后有了蓝色正方形、红色圆形...等需求。随着形状和颜色的添加,类就会越创建也多。

图片来源:https://refactoring.guru/design-patterns/bridge

之所以出现这样的问题,是因为我们再颜色和形状两个维度来扩展类。

java 复制代码
public abstract class Shape {
    private final String color;
    private final String shape;

    protected Shape(String color, String shape) {
        this.color = color;
        this.shape = shape;
    }

    public void draw() {
        System.out.println("图形形状:" + shape + ",颜色:" + color + "。");
    }
}

public class RedCircle extends Shape {

    protected RedCircle() {
        super("红色", "原型");
    }
}

怎么办?我们不能够为了新增的需求,无限的创建类。那这时候就需要用到桥接模式了。

Bridge 模式试图通过从继承切换到对象组合来解决这个问题。这意味着将其中一个维度提取到单独的类层次结构中,以便原始类将引用新层次结构的对象,而不是将其所有状态和行为都放在一个类中。

按照这种方法,我们可以将与颜色相关的代码提取到它自己的类中,其中包含两个子类: Red 和 Blue .然后,该 Shape 类获取指向其中一个颜色对象的引用字段。现在,形状可以将任何与颜色相关的工作委托给链接的颜色对象。该引用将充当 Shape and Color 类之间的桥梁。从现在开始,添加新颜色将不需要更改形状层次结构,反之亦然。

实现

java 复制代码
public interface Color {
    void apply();
}

public class Red implements Color {

    @Override
    public void apply() {
        System.out.println("使用了红色");
    }
}

public class Blue implements Color {

    @Override
    public void apply() {
        System.out.println("使用了蓝色");
    }
}

public abstract class Shape {

    protected final Color color;

    public Shape(Color color) {
        this.color = color;
    }

    public abstract void draw();
}

public class Circle extends Shape {

    public Circle(Color color) {
        super(color);
    }

    @Override
    public void draw() {
        System.out.println("画一个圆形");
        color.apply();
    }
}

使用

java 复制代码
public class Main {

    public static void main(String[] args) {
        Shape shape = new Circle(new Red());
        shape.draw();

        Shape shape2 = new Circle(new Blue());
        shape2.draw();
    }
}

输出

复制代码
画一个圆形
使用了红色
画一个圆形
使用了蓝色

这样修改看似与原来的类的数量一致,甚至还多了一个接口。但是随着形状和颜色的增加,类的数量会明显的减少,比如4个形状4个颜色,原来的继承方式需要 4 × 4 = 16 4 \times 4 = 16 4×4=16 而使用桥接模式后只需要 4 + 4 = 8 4+4=8 4+4=8。由原来的指数级增长,改为了常数级的增长。

实际的业务实例

在开源框架中的应用

何时使用

  • 当一个类需要在多个维度上变化时,使用继承会导致类爆炸的问题。
  • 当一个类需要独立地变化其抽象部分和实现部分时。
  • 当需要在抽象部分和实现部分之间建立一种透明的连接关系时。

与其他设计模式的联系

  • 适配器模式(Adapter Pattern):适配器模式旨在解决不兼容接口之间的问题,它通过将一个类的接口转换成客户端所期待的另一个接口,从而使原本不兼容的类可以协同工作。与桥接模式不同,适配器模式是为了使两个不兼容的接口能够协同工作,而桥接模式是为了将抽象部分和实现部分分离,使它们可以独立变化。
  • 装饰器模式(Decorator Pattern):装饰器模式旨在动态地给一个对象添加一些额外的职责,它通过组合的方式来达到这个目的。与桥接模式不同,装饰器模式是为了在不改变接口的情况下给对象添加额外的职责,而桥接模式是为了将抽象部分和实现部分分离,使它们可以独立变化。

虽然桥接模式与适配器模式和装饰器模式有一些相似之处,但它们的目的和应用场景有所不同。桥接模式主要用于将抽象部分和实现部分分离,使它们可以独立变化,从而提高系统的灵活性和可维护性。

总结

通过使用桥接模式,可以更好地管理类之间的关系,提高系统的灵活性和可维护性,同时也有利于解决类爆炸的问题。

参考资料

Bridge

相关推荐
Arbori_2621515 分钟前
获取oracle表大小
数据库·oracle
王强你强22 分钟前
MySQL 高级查询:JOIN、子查询、窗口函数
数据库·mysql
草巾冒小子23 分钟前
brew 安装mysql,启动,停止,重启
数据库·mysql
用户62799471826230 分钟前
南大通用GBase 8c分布式版本gha_ctl 命令-HI参数详解
数据库
斯汤雷38 分钟前
Matlab绘图案例,设置图片大小,坐标轴比例为黄金比
数据库·人工智能·算法·matlab·信息可视化
SQLplusDB1 小时前
Oracle 23ai Vector Search 系列之3 集成嵌入生成模型(Embedding Model)到数据库示例,以及常见错误
数据库·oracle·embedding
喝醉酒的小白1 小时前
SQL Server 可用性组自动种子设定失败问题
数据库
chem41111 小时前
Conmon lisp Demo
服务器·数据库·lisp
爱的叹息1 小时前
Java 连接 Redis 的驱动(Jedis、Lettuce、Redisson、Spring Data Redis)分类及对比
java·redis·spring
m0_555762902 小时前
QT 动态布局实现(待完善)
服务器·数据库·qt