技术成神之路:设计模式(十九)桥接模式

devtools/2024/10/20 4:16:15/

介绍

桥接模式(Bridge Pattern)是一种结构型设计模式,通过将抽象部分与它的实现部分分离,使它们都能够独立地变化。它的核心思想是将接口与实现解耦,从而使得两者可以独立地变化。

1.定义


桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。

2. 主要作用


  • 解耦桥接模式通过将抽象和实现分离,降低了系统的耦合度。
  • 扩展性:可以灵活地添加新的实现类和抽象类,而无需修改现有代码。
  • 减少类的数量:通过组合的方式,避免了大量的子类产生,降低了系统的复杂性。

3. 解决的问题


  • 类的数量急剧增加,导致管理和维护困难。
  • 修改一个实现类可能会影响多个子类,增加了系统的脆弱性。
  • 不同的实现类可能会在抽象类中被硬编码,缺乏灵活性。

4. 模式原理


包含角色:

  1. Abstraction(抽象类): 定义抽象类的接口,维护一个指向 Implementor 类型对象的指针。
  2. RefinedAbstraction(细化抽象类): 扩展抽象类,并实现具体业务逻辑。
  3. Implementor(实现类接口): 定义实现类的接口,不一定与抽象类的接口完全一致。
  4. ConcreteImplementor(具体实现类): 实现 Implementor 接口,并完成具体业务。

UML类图:
在这里插入图片描述
代码示例:
以图形绘制为例,展示如何使用桥接模式来分离图形(形状)与绘制方式(颜色)

// Implementor
interface Color {void applyColor();
}// ConcreteImplementor
class RedColor implements Color {public void applyColor() {System.out.println("Red.");}
}// ConcreteImplementor
class GreenColor implements Color {public void applyColor() {System.out.println("Green.");}
}// Abstraction
abstract class Shape {protected Color color;public Shape(Color color) {this.color = color;}abstract void draw();
}// RefinedAbstraction
class Circle extends Shape {public Circle(Color color) {super(color);}public void draw() {System.out.print("Circle filled with color ");color.applyColor();}
}// RefinedAbstraction
class Square extends Shape {public Square(Color color) {super(color);}public void draw() {System.out.print("Square filled with color ");color.applyColor();}
}

调用

public class BridgePatternDemo {public static void main(String[] args) {Shape redCircle = new Circle(new RedColor());Shape greenSquare = new Square(new GreenColor());redCircle.draw();  greenSquare.draw();  }
}

打印输出

Circle filled with color Red.
Square filled with color Green.

我觉得桥接模式的含义就两个字 分离,就像上面定义讲的,部分分离,独立变化,了解这点就明白了桥接模式的核心意义。

桥接模式的应用在我们生活中也很常见,比如一个大公司有许多部门,他们相互独立,又存在联系,各司其职,共同组成了公司的架构,可想而知,如果一家公司不存在部分划分,你既是开发又是测试,既是老板又是财务,那么运行起来是多么混乱。

举一反三

Java 的 I/O 库使用了桥接模式InputStreamOutputStream 是抽象类,定义了输入和输出的基本操作,而各种具体的实现类(如 FileInputStreamBufferedInputStream 等)则实现了这些操作。
ReaderWriter 类可以被视为实现类接口。而FileReaderFileWriter 则可以被视为具体实现类.

可以总结如下:

Abstraction: InputStream 和 OutputStream
RefinedAbstraction: FileInputStream 和 FileOutputStream
Implementor: Reader 和 Writer
ConcreteImplementor: FileReader 和 FileWriter

5. 优缺点


优点

  • 灵活性:可以在运行时切换不同的实现。
  • 易于扩展:可以通过增加新类而不是修改现有类来扩展系统。
  • 降低了系统复杂性:通过组合而非继承减少了类的数量。

缺点

  • 增加复杂性:引入了额外的抽象层次,增加了系统的复杂性。
  • 理解难度:对于初学者来说,理解桥接模式可能有一定难度。

桥接模式使用的不多,需要合理设计抽象与实现的分离,初期可能会有较高的设计成本。要是你的目标是个架构师,这个还是必须要掌握的。

6. 应用场景


  • 当一个类存在多个独立维度的变化时,可以使用桥接模式将这些维度分离开。
  • 当系统中存在多个组合变化时,通过桥接模式可以避免类的数量急剧增加。
  • 需要将抽象部分与实现部分解耦时。

7. 总结


桥接模式是一个强大且灵活的设计模式,通过将抽象与实现分离,降低了系统的耦合度和复杂性。虽然引入了额外的抽象层,但在需要高度灵活性和可扩展性的场景中,它提供了一种优雅的解决方案。在实际开发中,合理使用桥接模式能够有效提升系统的可维护性和可扩展性。


http://www.ppmy.cn/devtools/120851.html

相关文章

【系统架构设计师】经典论文:轮软件三层架构设计

更多内容请见: 备考系统架构设计师-核心总结目录 文章目录 摘要正文总结摘要 本人于 2022 年 1 月参与了中石化 XX 油田 XX 采油厂“用电管理系统”的项目建设,该系统建设目标是实现分单位、分线路、分系统评价、优化、考核,全面提升采油厂用 电管理水平。在该项目组中我担…

vue自定义div弹窗打开失败

在写自定义div弹窗的时候,实现类似el-dlaig打开关闭的效果。 1. showDialog的时候 div怎么也打不开,并且页面中也没有插入那块dom; 2. dialogVisible默认是true的时候是能正常展示div的 解决办法:类似el-dlalog的appen-to-body属性…

gRPC协议简介

gRPC 是谷歌开源的一套 RPC 协议框架。主要做两件事情:一是数据编码,二是请求映射。 数据编码 数据编码顾名思义就是在将请求的内存对像转化成可以传输的字节流发给服务端,并将收到的字节流再转化成内存对像。方法有很多,常见的…

C++基础补充(02)C++其他控制语句break continue goto等

文章目录 1. break2. continue 语句3. goto 语句goto的存在 4. 跳出多重循环4.1 goto 直接跳转4.2 C11及其后版本的 return 语句4.3 使用标志变量 在C中,控制语句用于管理程序的执行流程。常见有 break、continue 和 goto。 1. break break语句主要用于在循环或者s…

分层图 的尝试学习 1.0

分层图: 分层图的最短路: 又叫做 扩点最短路。不把实际位置看做是图上的点,而是把实际位置及其状态的组合,(一个点有若干的状态,所以一个点会扩充出来若干点)看做是图上的点,然后搜索…

第二十三节:学习拦截器或者使用AOP实现用户token参数请求检测(自学Spring boot 3.x的第六天)

这节记录下如何使用aop或者使用interceptor实现用户请求的是否带token,本文只是简单检查用户请求是否带参数token,并不对token的正确性进行验证。通常要从后台缓存中进行token校验。 第一种方式:拦截器方式 第一步:新建一个拦截器…

redis和mysql端口修改

因为之前有过被删库勒索的情况所以,今天记录一下怎么修改端口。 redis 要修改Redis的端口,您需要编辑Redis配置文件,通常名为redis.conf。 找到Redis配置文件: 在Linux系统上,该文件通常位于/etc/redis/redis.conf…

Python_partial函数和map同时用

partial 在Python中,functools 模块提供了一个 partial 函数,它可以用来创建一个部分函数。部分函数是指固定某些参数的函数。这在你需要重复使用同一个函数,但每次都只用到其中一部分参数的情况下非常有用。 下面是一个使用 functools.par…