我想要学会设计模式之桥接模式

603 阅读3分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战


我想学会设计模式之桥接模式

桥接模式:将抽象部分和具体实现部分分离,两者可独立变化,也可以一起工作。桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量。

其实将抽象部分与他的实现部分分离这句话不太好理解,实际上这并不是将抽象类与他的派生类分离,而是抽象类和它的派生类用来实现自己的对象。这样还是不能理解的话。我们就先来认清什么是抽象化,什么是实现化,什么是脱耦。

image-20210807234404203

什么是桥接模式

桥接模式:将抽象部分和具体实现部分分离,两者可独立变化,也可以一起工作。

在这种模式的实现上,需要一个对象担任“桥”的角色,起到连接的作用。


优点

  • 分离抽象接口及其实现部分。提高了比继承更好的解决方案。
  • 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
  • 实现细节对客户透明,可以对用户隐藏实现细节。

缺点

  • 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
  • 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。

应用场景

在封装开源库的组件时候,经常会用到这种设计模式。例如,对外提供暴露一个afterFinish函数,如果用户有传入此函数, 那么就会在某一段代码逻辑中调用。这个过程中,组件起到了“桥”的作用,而具体实现是用户自定义。


多语言实现

ES6 实现

JavaScript 中桥接模式的典型应用是:Array对象上的forEach函数。此函数负责循环遍历数组每个元素,是抽象部分。而回调函数callback就是具体实现部分。下方是forEach方法的实现

const forEach = (arr, callback) => {
    if (!Array.isArray(arr)) return;
    const length = arr.length;
    for (let i = 0; i < length; ++i) {
        callback(arr[i], i);
    }
};
// 以下是测试代码
let arr = ["a", "b"];
forEach(arr, (el, index) => console.log("元素是", el, "位于", index));

python3 实现

和 Js 一样,这里也是模拟实现一个for_each函数:它会循环遍历所有的元素,并且对每个元素执行指定的函数。

from inspect import isfunction
# for_each 起到了“桥”的作用
def for_each(arr, callback):
  if isinstance(arr, list) == False or isfunction(callback) == False:
    return
  for (index, item) in enumerate(arr):
    callback(item, index)
# 具体实现部分
def callback(item, index):
  print('元素是', item, '; 它的位置是', index)
# 以下是测试代码
if __name__ == '__main__':
  arr = ['a', 'b']
  for_each(arr, callback)