您的位置:首页 > 其它

设计模式学习之桥接模式

2015-04-02 14:17 204 查看
前面在学习抽象工厂模式的时候,抽象工厂能很好的处理多个产品族。产品族,实际是从不同的维度细分不同的产品。

桥接(bridge)模式,属于结构型设计模式,是从数据的另一个维度(行为)对数据进行划分,抽象出不同的行为来。该模式也充分体现了面向对象编程思想中的“组合/聚合复用(CARP)”、“高内聚低耦合"等等原则。网上摘录了一个例子很好的阐述了桥接模式:


调制解调器问题

感觉《敏捷软件开发-原则、模式与实践》中关于Bridge模式的例子很好。(《Java与模式》一书33章的对变化的封装一节也写得很不错,推荐大家读一读。它深入的阐述了《Design Patterns Explained》一书中"1)Design to interfaces. 2)Favor composition over inheritance. 3)Find what varies and encapsulate it"的三个观点。)。



如图所示,有大量的调制解调器客户程序在使用Modem接口。Modem接口被几个派生类HayesModem、USRoboticsModem和EarniesModem实现。它很好地遵循了OCP、LSP和DIP。当增加新种类的调制解调器时,调制解调器的客户程序不会受影响。

假定这种情形持续了几年,并有许多调制解调器的客户程序都在使用着Modem接口。现出现了一种不拨号的调制解调器,被称为专用调制解调器。它们位于一条专用连接的两端。有几个新应用程序使用这些专用调制解调器,它们无需拨号。我们称这些使用者为DedUser。但是,客户希望当前所有的调制解调器客户程序都可以使用这些专用调制解调器。他们不希望去更改许许多多的调制解调器客户应用程序,所以完全可以让这些调制解调器客户程序去拨一些假(dummy)电话号码。

如果能选择的话,我们会把系统的设计更改为下图所示的那样。



我们把拨号和通信功能分离为两个不同的接口。原来的调制解调器实现这两个接口,而调制解调器客户程序使用这两个接口。DedUser只使用Modem接口,而DedicateModem只实现Modem接口。但这样做会要求我们更改所有的调制解调器客户程序--这是客户不允许的。

一个可能的解决方案是让DedicatedModem从Modem派生并且把dial方法和hangup方法实现为空,就像下面这样:



几个月后,已经有了大量的DedUser,此时客户提出了一个新的更改。为了能拨国际电话号码、信用卡电话、PIN标识电话等等,必修对现有dial中使用char[10]存储号码改为能够拨打任意长度的电话号码。

显然,所有的调制解调器客户程序都必须更改。客户同意了对调制解调器客户程序的更改,因为他们别无选择。糟糕的是,现在必须要去告诉DedUser的编写者,他们必须要更改他们的代码!你可以想象他们听到这个会有多高兴。本来他们是不用调用dial的。

这就是许多项目都会具有的那种有害的混乱依赖关系。系统某一部分中的一个杂凑体(kludge)创建了一个有害的依赖关系,最终导致系统中完全无关的部分出现问题。

如果使用ADAPTER模式解决最初的问题的话,就可以避免这个严重问题。如图:



请注意,杂凑体仍然存在。适配器仍然要模拟连接状态。然而,所有的依赖关系都是从适配器发起的。杂凑体和系统隔离,藏身于几乎无人知晓的适配器中。

BRIDGE模式

看待这个问题,还有另外一个方式。现在,出现了另外一种切分Modem层次结构的方式。如下图:



这不是一个理想的结构。每当增加一款新硬件时,就必须创建两个新类--一个针对专用的情况,一个针对拨号的情况。每当增加一种新连接类型时,就必须创建3个新类,分别对应3款不同的硬件。如果这两个自由度根本就是不稳定的,那么不用多久,就会出现大量的派生类。

在类型层次结构具有多个自由度的情况中,BRIDGE模式通常是有用的。我们可以把这些层次结构分开并通过桥把它们结合到一起,而不是把它们合并起来。如图:



我们把调制解调器类层次结构分成两个层次结构。一个表示连接方法,另一个表示硬件。

这个结构虽然复杂,但是很有趣。它的创建不会影响到调制解调器的使用者,并且还完全分离了连接策略和硬件实现。ModemConnectController的每个派生类代表了一个新的连接策略。在这个策略的实现中可以使用sendlmp、receivelmp、diallmp和hanglmp。新imp方法的增加不会影响到使用者。可以使用ISP来给连接控制类增加新的接口。这种做法可以创建出一条迁移路径,调制解调器的客户程序可以沿着这条路径慢慢地得到一个比dial和hangup层次更高的API。

【说明】高内聚低耦合:将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联,就是解耦。
参考资料:http://blog.csdn.net/yhmhappy2006/article/details/7227017
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: