很多时候经常容易把桥接模式和适配器模式弄混。那什么时候用桥接,什么时候用适配器呢 ?

共同点:桥接和适配器都是让两个东西配合工作
不同点:出发点不同。
         适配器:改变已有的两个接口,让他们相容。
         桥接模式:分离抽象化和实现,使两者的接口可以不同,目的是分离。

所以说,如果你拿到两个已有模块,想让他们同时工作,那么你使用的适配器。
如果你还什么都没有,但是想分开实现,那么桥接是一个选择。

桥接是先有桥,才有两端的东西
适配是先有两边的东西,才有适配器

桥接是在桥好了之后,两边的东西还可以变化。

桥梁模式

抽象与实现

抽象不应该依赖于实现细节,实现细节应该依赖于抽象。

问题在于如果抽象B由于固有的原因,本身并不稳定,也有可能变化,怎么办?

举例来说

假如我们需要开发一个同时支持PC和手机的坦克游戏,游戏在PC和手机上功能都一样,都有同样的类型,面临同样的功能需求变化,比如坦克可能有很多种不同的型号:T50,T75,T90……

对于其中的坦克设计,我们可能很容易设计出来一个Tank的抽象基类,然后各种不同型号的Tank继承自该类;

另外的变化原因

但是PC和手机上的图形绘制、声效、操作等实现完全不同……因此对于各种型号的坦克,都要提供各种不同平台上的坦克实现:

这样的设计会带来很多问题:有很多重复代码,类的结构过于复杂,难以维护,最致命的是引入任何新平台,比如在TV上的Tank游戏,都会让整个类层级结构复杂化。

动机(Motivation)

思考上述问题的症结:事实上由于Tank类型的固有逻辑,使得Tank类型具有了两个变化的维度——一个变化的维度为“平台的变化”,一个变化的维度为“型号的变化”。

如何应对这种“多维度的变化”?如何利用面向对象技术来使得Tank类型可以轻松地沿着“平台”和“型号”两个方向变化,而不引入额外的复杂度?

意图(Intent)

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

——《设计模式》GoF

桥模式不能只是认为是抽象和实现的分离,它其实并不仅限于此。如下面的例子,两个都是抽象的部分。更确切的理解,应该是将一个事物中多个维度的变化分离。

对于这种在多个维度上都会有变化或扩充需求的项目来说,可以考虑引入桥接模式。或许你会说,不管是什么场景,不管什么模式,都可以是抽象场景的一个子类,但是,如果这样的话,4个场景和3种模式就会产生12个子类,而10个场景5种模式就会有50个子类。一味进行继承并不是什么好方法,桥接模式的思想是把继承转化为组合,把乘法(10*5=50)转化为加法(10+5=15)。

例说Bridge应用

版本一

先写各种不同的坦克型号类T50、T75等继承自Tank,然后再让各种平台的坦克继承自对应型号的类,如PCT50,PCT75继承自T50等。这样设计可能会有很多重复的代码,例PCT50和PCT75。

版本二

因为平台和坦克型号都是变化,所以我们把平台的变化作为属性放到基抽象类中。

平台实现类

下面是整个代码的骨架

Tank的型号,和Tank的平台都继承自各自的抽象类,因此它们的变化都不会影响到对方。而它们之间的关联,我们使用组合的方式,把平台类放到Tank类中作为属性。这再次体现了组合优先于继承的思想。多继承的方法就是版本一的代码,这种方式子类和父类的关系太紧,造成紧耦合。

这就是桥模式,把变化引出了基类Tank,使得Tank仅守与型号的变化。

应用程序

在环境交互中使用的都是抽象类,并且把平台实现隐藏,在应用程序中new平台的方式也可以根据情况用Singleton模式或者Abstract Factory模式等实现。

结构(Structure)

其中imp的地方就是一个组合。Abstraction就是我们之前例子中的Tank,它的子类RefinedAbstraction就是T50等型号。Implementor是TankPlatformImplementation类,ConcreteImplementorA和ConcreteImplementorB分别是PCTankImplementation和MobileTankImplementation。

整个设计模式的关键就是组合的使用。

Bridge模式的几个要点

Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象(Tank的型号)和实现(不同的平台)可以沿着格子的维度来变化。

所谓抽象和实现沿着各自维度的变化,即“子类化”它们(比如不同的Tank型号子类,和不同的平台子类),得到各个子类之后,便可以任意组合它们,从而获得不同平台上的不同型号。

Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。

下面是针对上面的例子,多继承接口的一种写法:

这样PCT50既需要写T50的实现,又要写Platform的实现,它把型号和平台的变化都引入了PCT50。这样就把两个本不该扭在一起的事务扭在了一起,这样的设计更加糟糕,而且也违背了类的单一职责原则。

Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。

桥模式并不同于适配器模式,适配器模式其实是一个事后诸葛亮,当发现以前的东西不适用了才去做一个弥补的措施。桥模式相对来说所做的改变比适配器模式早,它可以适用于有两个甚至两个以上维度的变化。

桥梁模式和适配器模式的区别相关推荐

  1. 桥接模式和适配器模式的区别

    很多时候经常容易把桥接模式和适配器模式弄混.那什么时候用桥接,什么时候用适配器呢 ? 共同点 桥接和适配器都是让两个东西配合工作 不同点 出发点不同.          1)适配器:改变已有的两个接口 ...

  2. 设计模式之桥梁模式和策略模式的区别

    桥接(Bridge)模式是结构型模式的一种,而策略(strategy)模式则属于行为模式.以下是它们的UML结构图. 桥梁模式: 策略模式: 在桥接模式中,Abstraction通过聚合的方式引用Im ...

  3. 设计模式——结构型模式之代理模式和适配器模式(类比+图解,从无到有,一文看懂几种模式的区别)

    设计模式 系列文章: 一.创建型模式--工厂模式 二.创建型模式--单例模式.原型模式 三.创建型模式--建造者模式 四.结构型模式--装饰者模式 五.结构型模式--代理模式.适配器模式 文章目录 设 ...

  4. 【设计模式】 桥梁模式

    1.定义 1.1 标准定义 桥梁模式( Bridge Pattern) 也叫做桥接模式, 是一个比较简单的模式, 其定义如下: Decouple an abstraction from its imp ...

  5. 框架模式和设计模式的区别

    框架模式和设计模式的区别 有很多程序员往往把框架模式和设计模式混淆,认为MVC是一种设计模式.实际上它们完全是不同的概念.[7] 框架.设计模式这两个概念总容易被混淆,其实它们之间还是有区别的. 框架 ...

  6. 代理模式vs适配器模式vs外观模式

    一.定义 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问. 适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,使得原本接口不兼容而不能一起工作的那些类可以 ...

  7. MVC、MVP、MVVM模式的概念与区别

    ------<MVC.MVP.MVVM模式的概念与区别> 前言: 预热: 挨个讲讲: MVC MVP MVVM 结尾: 前言: 首先MVC,MVP,MVVM都是为了解决UI页面与逻辑代码分 ...

  8. 设计模式GOF23之-------------------结构型模式(适配器模式、代理模式、桥接模式、装饰模式、组合模式、外观模式、享元模式)

    一 结构型模式 二 适配器模式 下面我将用代码模拟键盘usb接口和ps/2的转接器 的适配器过程: 首先定义客户需求: package GOF23;public interface Target {v ...

  9. 初探Java设计模式2:结构型模式(代理模式,适配器模式等)

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

最新文章

  1. 统计学习方法笔记(六)-非线性支持向量机原理及python实现
  2. 【HDU - 3951】Coin Game (博弈,猜规律,对称博弈)
  3. 东莞华勤通讯软件测试怎么样,【社招】华勤通讯NBD测试验证部急聘岗位-东莞...
  4. 使用EntityFramework Core和Enums作为字符串的ASP.NET Core Razor页面——第二部分
  5. HTML页面的基本代码结构是什么?
  6. 【电脑帮助】解决Wind10系统spacedesk程序开机自启动的问题
  7. 洛克人红色思考型机器人叫什么_如何让机器人“好好说话”?
  8. jq toggle()方法学习
  9. oracle储存过程与函数
  10. 3D蓝光影碟的SSIF文件
  11. 十进制 二进制 十六进制 八进制
  12. eu指什么_鞋码eu是什么意思 鞋子尺码eu对照表
  13. centos ffmpeg 加水印
  14. 【sv】getenv 【import “DPI-C“】
  15. 2021年中国开源优秀人物揭晓
  16. 转:浅谈程序员的英语学习
  17. 了解一下国标和行标的代号
  18. 网赚点击通用教程! - 健康程序员,至尚生活!
  19. 时之扉手游如何在电脑上玩 时之扉手游模拟器教程
  20. 远程协助——帮助你解决电脑问题

热门文章

  1. DirectX11 With Windows SDK--24 Render-To-Texture(RTT)技术的应用
  2. [vim]高亮查找匹配
  3. 正则表达式 非捕获性分组
  4. 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试...
  5. 只要存心谦卑,各人看别人比自己强。
  6. 畅谈程序人生暨孙鑫老师与读者交流会
  7. 【leetcode】股票买卖系列总结
  8. BigDecimal 与double 转化失真
  9. Cisco packet tracer6.0下的网络工程实训
  10. python框架Flask学习笔记之get和post请求