「聊设计模式」之桥接模式(Bridge)

🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎持续关注&&收藏&&订阅!


前言

设计模式是程序员不可或缺的一部分。它们提供了一种通用的方法来解决常见的编程问题,从而提高了代码的可读性和可维护性。在本文中,我们将聊一下设计模式中的"桥接模式"。

摘要

桥接模式是一种结构性设计模式,它允许我们将一个抽象类和它的实现分离开来,从而可以独立地改变它们的实现,而不会影响到客户端代码。

桥接模式

模式概述

桥接模式是一种结构性设计模式,它将抽象和实现分开,以便它们可以独立地变化。它通过使用组合来代替继承来实现这个目标。

在桥接模式中,有两个类层次结构:抽象类和实现类。抽象类定义了一个接口,它包含了一些基本的操作方法。实现类实现了这些操作方法,并将它们映射到具体的实现上。通过这种方式,客户端代码和具体的实现之间就解耦了。

模式结构

桥接模式的结构包括四个主要部分:

  1. 抽象化(Abstraction):定义抽象类,并包含一个指向实现化对象的引用,抽象类的接口将调用实现化类中的方法。

  2. 实现化(Implementor):定义实现化接口,具体实现化类将实现此接口。

  3. 具体抽象化(Refined Abstraction):扩展抽象化接口以支持更多功能,实现类将实现这些方法。

  4. 具体实现化(Concrete Implementor):实现实现化接口的类,并提供具体实现。

其结构图如图所示:

模式优势

使用桥接模式的主要优势在于它能够将抽象和实现分离开来,并将它们独立地变化。这意味着,如果你需要改变实现方式,你只需要改变实现类,而不需要改变客户端代码。

此外,使用桥接模式可以提高代码的可读性和可维护性。因为它将功能分解成小的模块,而不是大而复杂的类。这使得代码更容易理解、调试和修改。

模式缺点

桥接模式的主要缺点在于它增加了代码的复杂性。因为它需要将抽象和实现分开,所以需要增加更多的类和层次结构。这可能会使代码难以理解、调试和维护。

适用场景

桥接模式适用于以下场景:

  • 当你需要将一个抽象类和它的实现分开时。
  • 当你需要支持多种平台或多种操作系统时。
  • 当你需要改变一个类的实现方式时,而不想影响到客户端代码。

模式实现

下面通过一个例子来说明桥接模式的实现过程。

假设我们要设计一个图形库,其中包含两个基本功能:绘制不同种类的图形和使用不同的颜色进行填充。我们可以使用桥接模式来实现这个图形库,其中抽象部分为Shape,实现部分为Color,桥接接口为DrawAPI

先看一下Shape的抽象类:

java 复制代码
package com.example.javaDesignPattern.bridge;

/**
 * 抽象类
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 11:19
 */
public abstract class Shape {
    protected DrawAPI drawAPI;

    public Shape(DrawAPI drawAPI) {
        this.drawAPI = drawAPI;
    }

    public abstract void draw();
}

可以看到,Shape包含了一个对DrawAPI的引用,并且定义了一个抽象的draw方法,用于绘制图形。

再看一下DrawAPI的接口:

java 复制代码
package com.example.javaDesignPattern.bridge;

/**
 * 抽象接口
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 11:19
 */
public interface DrawAPI {
    public void draw();
}

DrawAPI定义了一个draw方法,Shape的实现类将通过它来使用不同的颜色进行填充。

然后是Shape的实现类:CircleRectangle和Triangle

java 复制代码
package com.example.javaDesignPattern.bridge;

/**
 * Shape的实现类
 * 
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 11:20
 */
public class Circle extends Shape {
    private int x, y, radius;

    public Circle(int x, int y, int radius, DrawAPI drawAPI) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    public void draw() {
        drawAPI.draw();
    }
}
java 复制代码
package com.example.javaDesignPattern.bridge;

/**
 * Shape的实现类
 * 
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 11:21
 */
public class Rectangle extends Shape {
    private int x, y, width, height;

    public Rectangle(int x, int y, int width, int height, DrawAPI drawAPI) {
        super(drawAPI);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    public void draw() {
        drawAPI.draw();
    }
}
java 复制代码
package com.example.javaDesignPattern.bridge;

/**
 * Shape的实现类
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 11:22
 */
public class Triangle extends Shape {
    private int x1, y1, x2, y2, x3, y3;

    public Triangle(int x1, int y1, int x2, int y2, int x3, int y3, DrawAPI drawAPI) {
        super(drawAPI);
        this.x1 = x1;
        this.y1 = y1;
        this.x2 = x2;
        this.y2 = y2;
        this.x3 = x3;
        this.y3 = y3;
    }

    public void draw() {
        drawAPI.draw();
    }
}

可以看到,它们都继承了Shape,并实现了draw方法。在构造方法中,将DrawAPI对象传递给了Shape的构造方法,从而实现了抽象部分和实现部分的连接。

最后是Color的实现类:RedGreenBlue

java 复制代码
package com.example.javaDesignPattern.bridge;

/**
 * Color的实现类
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 11:24
 */
public class Red implements DrawAPI {
    public void draw() {
        System.out.println("fill with red");
    }
}
java 复制代码
public class Green implements DrawAPI {
    public void draw() {
        System.out.println("fill with green");
    }
}
java 复制代码
public class Blue implements DrawAPI {
    public void draw() {
        System.out.println("fill with blue");
    }
}

它们都实现了DrawAPI接口,并提供了具体的draw方法,用于绘制不同的颜色。

最后我们可以编写一个测试用例来验证桥接模式的实现:

java 复制代码
package com.example.javaDesignPattern.bridge;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 11:15
 */
public class Client {

    public static void main(String[] args) {
        Shape circle = new Circle(100,100, 10, new Red());
        circle.draw();

        Shape rectangle = new Rectangle(50, 50, 20, 30, new Green());
        rectangle.draw();

        Shape triangle = new Triangle(10, 20, 30, 40, 50, 60, new Blue());
        triangle.draw();
    }
}

执行结果如下:

代码分析:   如上代码是一个简单的示例程序,其中定义了一个Client类。在main方法中,创建了三个形状对象circlerectangletriangle,并使用draw方法绘制了它们。

这三个形状对象分别是:

  • Circle:圆形,构造函数中参数依次为圆心位置x、y坐标、半径和颜色对象。
  • Rectangle:矩形,构造函数中参数依次为左上角位置x、y坐标、宽度、高度和颜色对象。
  • Triangle:三角形,构造函数中参数依次为三个顶点的x、y坐标和颜色对象。

在这里,颜色对象是使用了简单工厂模式创建的,包括RedGreenBlue

小结

在本文中,我们介绍了桥接模式,它是一种结构性设计模式,用于将一个抽象类和它的实现分开。我们看了一个简单的例子来理解这个模式,然后讨论了它的优点、缺点和适用场景。最后,我们提供了一些代码和测试用例来帮助你在实际中应用这个模式。

附录源码

如上涉及代码均已上传同步在 GitHub,提供给同学们参考性学习。

总结

桥接模式是一种非常有用的设计模式,可以将抽象和实现分开,从而提高代码的可读性和可维护性。它可以帮助我们实现更灵活、更可扩展的代码,适用于需要支持多种平台或多种操作系统的情况。如果您正在开发一个需要支持多种平台的应用程序,或者需要改变一个类的实现方式,而不想影响到客户端代码,那么您应该考虑使用桥接模式。

☀️建议/推荐你


如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

📣关于我


我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。

相关推荐
武子康3 分钟前
大数据-258 离线数仓 - Griffin架构 配置安装 Livy 架构设计 解压配置 Hadoop Hive
java·大数据·数据仓库·hive·hadoop·架构
豪宇刘1 小时前
MyBatis的面试题以及详细解答二
java·servlet·tomcat
秋恬意1 小时前
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
java·数据库·mybatis
刘大辉在路上1 小时前
突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除
git·后端·gitlab·版本管理·源代码管理
FF在路上2 小时前
Knife4j调试实体类传参扁平化模式修改:default-flat-param-object: true
java·开发语言
真的很上进2 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
众拾达人3 小时前
Android自动化测试实战 Java篇 主流工具 框架 脚本
android·java·开发语言
皓木.3 小时前
Mybatis-Plus
java·开发语言
不良人天码星3 小时前
lombok插件不生效
java·开发语言·intellij-idea
守护者1703 小时前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习