桥接模式,属于结构型模式。
意图:将抽象部分与它的实现部分分离,使他们都可以独立的变化。
这句话其实有点难理解, 在软件工程里面,哪些部分是抽象,哪些部分是实现呢?其实这里没有一个具体的定义。下面几句摘自其他书籍,便于我们理解:
1:《大话设计模式》:实现系统可能有多角度分类,每一种分类都有可能变化,那么就把多种角度分离出来让他们独立变化,减少他们之间的耦合。
2:《设计模式java版》:桥接模式是一种很实用的结构型设计模式,如果软件系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使两者可以独立扩展,让系统更加符合“单一职责原则”。与多层继承方案不同,它将两个独立变化的维度设计为两个独立的继承等级结构,并且在抽象层建立一个抽象关联,该关联关系类似一条连接两个独立继承结构的桥,故名桥接模式。
在这里我们其实没有绝对的定义抽象部分和显示部分,我们只知道把两个独立的维度分离出来,并且不影响他们各自的变化的结构就是桥接模式的结构。
UML图:
今天还是以《完美国际》游戏为例,来做这个demo(谁让我那么喜欢这款游戏)
问题:
在游戏中,我们有很多职业,比如武侠,妖兽,羽芒等等,这些职业也都可以拿上武器,斧头,长枪,刀等等;其实在这里,我们已经有了两个维度,职业和武器。那么怎么才能让每个职业都可以拿上自己的武器,或者反过来说,这些武器,每个职业都可以使用呢?
方案1:
有人会说,这还不简单,我们可以设计很多职业,比如,刀武侠,刀妖兽,刀羽芒,斧头武侠,斧头妖兽,斧头羽芒等等。如图:
方案1缺陷:首先这样设计是没问题的,但是前面已经说过,职业和武器本身就是两个不同维度的东西,现在非要整合在了一起,代码耦合性太高不说,更是违背了设计模式的单一职责原则,接口隔离原则,开闭原则。
方案2:
使用桥接模式,把职业和武器两维度桥接在一起,但是每个维度又可以独立发展,如图:
图中,职业和武器是两个独立的维度,他们互不影响,主要是由职业抽象类进行的两个维度的桥接,代码如下:
武器纬度(武器接口和具体实现):
职业纬度:
测试类:
方案二总结:图中可以看到,武器和职业两个纬度,互不影响,不论以后开通多少武器和职业,两个类互不影响,各自发展。完全符合单一职责原则。图中在职业抽象类中引入了武器的接口引用进行桥接,面向了接口,降低了耦合。
总结:
1、桥接模式实现了抽象化与实现化的脱耦。他们两个互相独立,不会影响到对方。
2、对于两个独立变化的维度,使用桥接模式再适合不过了。
3、对于“具体的抽象类”(我们将抽象类的属性都让实现类接口去做啦)所做的改变,是不会影响到客户。