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

举报
bug菌 发表于 2023/09/25 17:03:30 2023/09/25
【摘要】 桥接模式是一种结构性设计模式,它允许我们将一个抽象类和它的实现分离开来,从而可以独立地改变它们的实现,而不会影响到客户端代码。


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


大家下午好,我是bug菌,今天我们继续聊设计模式。

前言

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

摘要

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

桥接模式

概述

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

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

模式结构

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

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

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

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

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

如下是桥接模式的UML类图:

image.png

优缺点

模式优势

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

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

模式缺点

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

适用场景

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

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

模式实现

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

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

先看一下Shape的抽象类:

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的接口:

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

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();
    }
}
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();
    }
}
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

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");
    }
}
public class Green implements DrawAPI {
    public void draw() {
        System.out.println("fill with green");
    }
}
public class Blue implements DrawAPI {
    public void draw() {
        System.out.println("fill with blue");
    }
}

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

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

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();
    }
}

执行结果如下:

image.png

代码分析

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

这三个形状对象分别是:

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

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

小结

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

附录源码

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

总结

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

☀️建议/推荐你


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

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

📣关于我

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


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。