桥接模式: Bridge

简介
桥接模式是结构型模式 (Structural Patterns) 的一种.

Making even a simple change to a monolithic codebase is pretty hard because you must understand the entire thing very well. Making changes to smaller, well-defined modules is much easier.

如果软件系统中某个类存在多个独立变化的维度, 通过该模式可以将这多个维度分离出来, 使他们可以独立扩展, 让系统更加符合"单一职责原则 (SRP)". 与多层继承方案不同, 它将多个独立变化的维度设计为多个独立的继承等级结构, 并且在抽象层建立一个抽象关联, 该关联关系类似一条连接多个独立继承结构的桥, 故名桥接模式.
桥接模式用一种巧妙的方式处理多层继承存在的问题, 用抽象关联取代了多层继承,将类之间的静态继承关系转换为动态的对象组合关系, 使得系统更加灵活, 并易于扩展, 同时有效控制了系统中类的个数.
简单的例子

interface Shape {
val shapeType: ShapeType
}

abstract class Circle : Shape {
val shapeType = TypeCircle
abstract val shapeColor: ShapeColor

}

abstract class Square : Shape {
val shapeType = TypeSquare
abstract val shapeColor: ShapeColor

}

class RedCircle : Circle() {…}
class RedSquare : Square() {…}
class BlueCircle : Circle() {…}
class BlueSquare : Square() {…}

复制代码在这个例子中, 无论增加形状, 还是增加颜色, 都会导致子类数量快速增加. 解决方案是划分成两个独立变化的维度: Type 和 Color.

abstract Shape(val shapeColor: ShapeColor) {
abstract val shapeType: ShapeType
}

class Circle(val shapeColor: ShapeColor) : Shape(ShapeColor) {
val shapeType = TypeCircle

}

class Square(val shapeColor: ShapeColor) : Shape(ShapeColor) {
val shapeType = TypeSquare

}
复制代码现在, 增加颜色不会再导致子类数量增加了. Shape 和 Color 直接的关系就是那座桥.
基本概念
在 GoF 中, 桥接模式的定义如下:

Abstraction:拥有一个 Implementation 类型的对象引用
Implementation:Implementation 和 Abstraction 接口并不一定完全一致,实际上这两个接口可以完全不一样, Implementation 提供具体操作方法,而 Abstraction 提供更高层次的调用
Concrete Implementation:实现 Implementation 接口,给出具体实现
Refined Abstraction:扩展 Abstraction 中的接口定义
Client: 连接 Abstraction 和 Implementation

真实的例子
QWE9999ABCooosdf.elkwo.com/app&httpsQWE9999ABC
伪代码见: refactoring.guru/design-patt…

遥控器的基类 (Remote) 中包含一个设备的引用 (device), 所有的遥控器都可以通过通用的设备接口 (Device interface) 控制设备.

通用设备接口使得遥控器代码可以复用于遥控多种不同的设备 (Radio / TV).
通过继承遥控器基类, 可以实现只有两个按钮的简单遥控器, 或是带触摸屏的复杂遥控器.

其它真实的例子

  • 驱动程序 / JDBC
    应用程序使用驱动程序的方式是桥接模式的一个常见例子.
    外设驱动按照制定好的接口操作外设, 使用该驱动的应用是一个 Abstraction, 它的运行结果取决于它使用的是哪一个外设+驱动. 每个驱动程序都是适配器模式 (Adapter) 的一个例子, 而使用驱动程序的应用是桥接模式的一个例子. 桥接模式将应用的开发和驱动的开发分离开来.
    JDBC 是用于执行 SQL 的 Java 接口, JDBC 驱动就是实现了该接口的类. 任何一个数据库只要提供了 JDBC 驱动, Java 的数据库应用程序就可以操作它. JDBC 的这种架构将 Abstraction 和 Implementation 相分离, 使得数据库应用和数据库能够独立的发展, 是 Bridge 模式的一个极好的例子.
  • VCS (Version Control System)
    IDEA 的 VSC, 或者 Sourcetree 之类的软件, 都可以在同样一套 UI 下, 用同样的概念 (比如 History, Diff) 操作不同的版本控制系统 (比如 Git, Svn).
    应用场景
    当一个应用/类的某个功能要支持多个变体(比如支持多个数据源)
    一个应用/类越大, 弄清楚或改动的的代价就越大. 对于一个变体的改动可能会导致整个应用/类内的大量改动, 这经常会导致各种问题. Bridge 模式可以把应用/类拆分成多个独立的结构, 之后的改动就在各自的结构中, 让代码的改动影响最小化.
    当一个类在多个正交的维度上可扩展时
    Bridge 模式建议将每个维度抽象成独立的继承关系, 这样之前的类可以将相关的功能和扩展代理给对应的维度去做, 而不是完全自己做.
    如果你希望支持运行时切换实现 (Implementation)
    虽然不是最重要的, 但 Bridge 模式允许你切换 Abstraction 中引用的 Implementation.
    这可能是 Bridge 模式容易和策略模式 (Strategy) 混淆的一个原因. 注意: 设计模式呈现的不仅是最终的代码, 还有解决问题的思路.
    优缺点
    优点

可以用来创建跨平台的应用.
Client 和 Abstraction 交互, 不暴露 Implementation 的细节.
开闭原则: 可以分别增加 Abstraction 和 Implementation 的子类而不相互影响.
单一职责原则: Abstraction 或 Implementation 的开发人员可以 Focus 各自的代码.

缺点

如果一个类的功能之间功能之间相关性较强, 使用 Bridge 模式可能会让代码变得更复杂.

和其它设计模式的关系

Bridge, State, Strategy (Adapter 在某种程度上也算) 有一些相似, 这些设计模式都采用了将功能代理给其它类去做的方式. 但是, 他们解决的问题并不相同. 设计模式呈现的不仅是最终的代码, 还有解决问题的思路.
Abstract Factory 可以和 Bridge 一起使用, 通常用于 Abstraction 只能使用特定的 Implementation 的情况. 在这种情况下, 可以用 Abstract Factory 封装 Client 代码中建立 Abstraction 和 Implementation 连接的部分.
Builder 可以和 Bridge 一起使用, Director 作为 Abstraction, 多个 Builder 作为 Implementation.

本文的大部分内容来自: refactoring.guru/design-patt…
参考:

blog.csdn.net/yanbober/ar…
blog.csdn.net/u013256816/…
设计模式 Java 手册

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值