设计模式深入浅出(三)接口适配——桥接

OK,通过前两章,我们一起看了创建型模式。

现在进入接口适配类型模式。

所谓接口适配,就是将不兼容的接口,能够共同合作,同时合理的控制其耦合度。

现在介绍第一个接口适配模式,桥接。

桥接

设想我们要设计一款绘图软件,它包括基础的绘图功能:绘制静态图片。同时它要求支持Mac和Windows两套操作系统。

这里我们分析一下,由于画图的实现代码,不同平台是有不同的实现。那么,我们不得以要为Windows和Mac写两套代码,
这里写图片描述

在这里,BaseDrawer中没有实际的代码实现,只有一些共有的接口定义(实际的代码实现需要在运行时根据其操作系统切换),在MacStaticDrawer和WindowsStaticDrawer中,有其平台相关的draw的代码实现。

到目前为止,一切都很好,似乎也很有扩展性,当我们需要支持Linux时,只需要再来一个子类LinuxStaticDrawer即可。

注意,我们现在的Drawer只能够支持绘制静态的图片。当我们需要绘制动态图片怎么办呢?由于动态图片和静态图片是两种完全不同的图片类型(不是is a的关系),所以我们不能够直接继承StaticDrawer来分别对Mac和Windows两个平台上进行扩展。但是我们的动态图片绘制确实是Drawer的一种,因此,我们需要直接将DynamicDrawer继承与BaseDrawer。为了同时支持Mac与Windows,我们还需要MacDynamicDrawer和WindowsDynamicDrawer。

这里写图片描述

可以想象,如果我们再基于BaseDrawer创建一种Drawer,那么为了支持Mac与Windows,同样我们需要MacXXDrawer和WindowsXXDrawer子类。

我们可以得出如下结论

假设Drawer的种类为n,需要支持的平台为m,则需要的类数量为n * m。

这种子类增长的速度是惊人的,比如我们需要支持Linux平台,则需要类数量为2 * 3 = 6。 如果我们需要引入另一种新的Drawer,则类数量为 3 * 3 = 9;

为什么会产生这么多子类呢?让我们回到上面的类图中,找下原因。

这里写图片描述

图中,绿色部分子类产生的原因是:为了在Mac和Windows上不同的实现。
蓝色部分子类产生的原因是:一种新类型的Drawer,同时为了支持Mac和Windows上不同的实现。

也就是说,这里有两种原因会使得子类生成:1. 为了不同平台的具体实现 2. 为了基于BaseDrawer的新的类型,也就是新的接口层。也就是说,造成基类子类化的原因多于一个

现在我们这个类似乎承担了过多的职责,虽然没有直接违反单一职责的原则,但是我们可以感觉到,目前的类结构是可以修改的。

我们上面说了,绿色部分代表了具体的平台实现,蓝色部分代表了抽象接口的扩展。那么,是否可以将这两部分抽象出两个类呢?当然可以,如下图:

这里写图片描述

那么,抽象接口需要实现接口,该如何做呢?

很简单,在抽象接口向平台实现架”一座桥“,及抽象接口层引用实现层:
这里写图片描述

这就是桥接模式,他分离的向外提供的抽象接口与实现,使这两个方面均可以独立的变化,而互不依赖。

桥梁模式的用意是”将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化”。这句话有三个关键词,也就是抽象化、实现化和脱耦

下图是《设计模式》一书中,桥接模式的UML:

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值