设计模式之Bridge(桥梁)模式

在介绍设计模式之前,我们先考虑两个问题:是什么导致设计的不完美,设计者的理想是什么?

——变化,无法避免的、经常的需求变化导致设计的不完美;设计者的理想:当需求变化的时候,尽可能少的修改代码就可以满足新的需求。就是为了实现设计者的理想,各种设计模式被人们开发出来。

为了能更好的的理解Bridge模式,我们用一个例子进行详述:
有一个叫做HuntBird的游戏,里面需要表示各种各样的鸟类,一开始是这样设计的:
设计模式之Bridge(桥梁)模式_第1张图片
鸽子和老鹰的显示方法不同,所以在父类中留了一个显示接口让子类各自实现自己的方法,这样设计没什么问题,接下来发生了需求变化,鸟类都要会飞,由于老鹰和各自都会飞,所以我们首先想到的就是在父类中添加一个飞的方法,通过继承关系,子类重用了父类的方法,提高了代码的可维护性:
设计模式之Bridge(桥梁)模式_第2张图片
但是如果我们要增加一个鸟类——企鹅类呢?难道说直接继承鸟类?企鹅会飞么?所以我们可以把父类方法中的飞这个方法改为抽象方法让子类去实现:
设计模式之Bridge(桥梁)模式_第3张图片
这里对“飞”使用了多态:父类给出接口,子类给出具体实现,这样做是没什么问题,但是这里鸽子和老鹰“飞”的代码出现了重复。
改进方法:再次使用继承
设计模式之Bridge(桥梁)模式_第4张图片
这样是解决了老鹰鸽子代码冗余的问题,但是现在需求变化了,需要增加一个游泳的行为,又该怎么设计:
首先想到的方法是:增加两个类,修改所有子类的继承关系:
设计模式之Bridge(桥梁)模式_第5张图片
是不是感觉有点麻烦了,以后要是再增加更多的行为呢?
使用继承关系只会使得问题越来越复杂,这里我们该想到面向对象的设计原则——组合优先:优先使用组合,而不是继承 。
继承的优缺点:优点:继承可以很容易的修改或扩展父类实现;缺点:继承破坏封装,因为父类的实现细节完全暴露给子类;父类的实现发生改变,则子类必受牵连,继承是静态的,不能在运行时发生改变,不灵活。
组合复用的优缺点:优点:组合复用不破坏封装,属于黑盒复用;是动态的,可以把成员对象动态替换为另一个类型相同的对象;缺点:对象的数量会增加,使用委托会使系统变复杂。
我们先来看看上述类图中的变化点:鸟类的行为易变,还有鸟类的具体类型易变。
设计模式之Bridge(桥梁)模式_第6张图片
根据面向对象的设计原则,封装可变性,发现代码容易变化的部分,封装之,使它和不容易变化的部分独立开来。我们将先将鸟类封装起来,再将鸟类的行为封装起来:
设计模式之Bridge(桥梁)模式_第7张图片        设计模式之Bridge(桥梁)模式_第8张图片
这里我们在想,鸟类跟行为是什么关系?很明显是鸟类拥有行为,而关于鸟类行为的具体实现,委托“行为“类来完成:
设计模式之Bridge(桥梁)模式_第9张图片
这就是桥梁模式,他有什么效果呢?如果我们想增加一种鸟类”鹅“,相应的我们只需要增加一个叫”鹅“的类,增加鸭子游泳的行为或其他行为就行, 原有代码不需要改动!体现了开闭原则;
设计模式之Bridge(桥梁)模式_第10张图片
使用桥梁模式的效果
当需求改变的时候(增加动物或行为),只需要简单添加几个类
对原有代码不需要改动
保证了代码的稳定,提高了可维护性

桥梁模式结构:

设计模式之Bridge(桥梁)模式_第11张图片
意图:
将抽象部分与它的实现部分分离,使它们都可以独立地变化
适用性:
将继承关系转换为组合关系,从而降低了系统间的耦合,减少了代码冗余
抽象和它的实现部分可以独立变化
类的抽象以及它的实现都可以通过生成子类的方法加以扩充
实现部分的修改不会对客户产生影响

你可能感兴趣的:(编程思想)