设计模式之桥接模式

结构型模式之桥接模式

  • 桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”。与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系类似一条连接两个独立继承结构的桥,故名桥接模式。
  • 桥接模式用一种巧妙的方式处理多层继承存在的问题,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效控制了系统中类的个数。桥接定义如下:
  • 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
  • 在桥接模式结构图中包含如下几个角色:
    • Abstraction(抽象类):用于定义抽象类的接口,它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法。
    • RefinedAbstraction(扩充抽象类):扩充由Abstraction定义的接口,通常情况下它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法。
    • Implementor(实现类接口):定义实现类的接口,这个接口不一定要与Abstraction的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,在Abstraction中不仅拥有自己的方法,还可以调用到Implementor中定义的方法,使用关联关系来替代继承关系。
    • ConcreteImplementor(具体实现类):具体实现Implementor接口,在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时,ConcreteImplementor对象将替换其父类对象,提供给抽象类具体的业务操作方法。

实例

  • 从上面的这个实例我们可以看出,如果使用多层继承的话,那么我们可以定义是三个抽象类(台式机,笔记本,平板电脑),在这个三个抽象类的下面每个都有三个不同品牌的具体实现类,那么总共要有3x3=9个具体的实现类。不仅仅是类的数量多,在扩展性能上也是成倍的增加,如果想要添加一个品牌,那么需要添加三个类,这个是极其浪费的。
  • 针对上面的缺点,我们可以使用桥接模式,将电脑分类,品牌分类分成两个维度,如下图:
  • 其中Computer是一个抽象类,不是接口,其中Brand(品牌)是其中的成员变量,我们就完成了一个电脑具有不同品牌,那么如果我们想添加一个品牌,就只是添加一个具体的实现类即可,就不需要添加三个了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序猿DD

《JS正则表达式教程》汇总

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表通常被用...

3496
来自专栏ATYUN订阅号

使用Python建立你数据科学的“肌肉记忆”

你是否曾在在搜索语法时,因为打断了数据分析流而感到沮丧?为什么你在屡次查找后仍然不记得它?这是因为你还没有足够的练习来为它建立“肌肉记忆”。

882
来自专栏前端笔记

【 数字游戏 2048 】原生 JavaScript 做小游戏

原生 JavaScript 2048 源码 : <!doctype html> <html> <head> <title>2048</title> <m...

42813
来自专栏偏前端工程师的驿站

(cljs/run-at (JSVM. :all) "一次说白DataType、Record和Protocol")

1104
来自专栏IT大咖说

面向前端开发者的V8性能优化

摘要 V8是一个由丹麦Google使用C++开发的开源JavaScript引擎,用于Google Chrome中,目前该JavaScript引擎已用于其它项目的...

39710
来自专栏糊一笑

几个关于js数组方法reduce的经典片段

以下是个人在工作中收藏总结的一些关于javascript数组方法reduce的相关代码片段,后续遇到其他使用这个函数的场景,将会陆续添加,这里作为备忘。 jav...

4599
来自专栏JetpropelledSnake

Python面试题之回调函数

编程分为两类:系统编程(system programming)和应用编程(application programming)。所谓系统编程,简单来说,就是编写库;...

1612
来自专栏偏前端工程师的驿站

(cljs/run-at (JSVM. :all) "一次说白DataType、Record和Protocol")

前言  在项目中我们一般会为实际问题域定义领域数据模型,譬如开发VDOM时自然而言就会定义个VNode数据类型,用于打包存储、操作相关数据。clj/cljs不单...

1968
来自专栏java一日一条

Java 枚举查找并不抛异常的实现

Java Enum是一个非常有用的功能,但很多人通常并不能充分利用,这是因为一些库不会优先择用该功能。通常我们也可以正确使用Java枚举功能,但在许多代码库中往...

1113
来自专栏程序员的酒和故事

跟Google学写代码--Chromium工程中用到的C++11特性

Ttile 跟Google学写代码--Chromium工程中用到的C++11特性 Chromium是一个伟大的、庞大的开源工程,很多值得我们学习的地方。 《跟...

4604

扫码关注云+社区

领取腾讯云代金券