【转】设计模式学习笔记(7)-桥接
桥接(Bridge)这个词用的还是挺广的,意指将相似的但无法沟通的东西连接起来,比如说网桥就是连接两个网段的。
设计模式中的Bridge模式还是比较容易理解的,但是貌似不太常用,当然在GUI编程上用的还是比较多的。举个例子吧,面包长要生产几种类型的面包,如白面包(WhiteBread)和黑面包(BlackBread),当然我们有一个抽象的面包(Bread),现在的类图是这样的:
没有任何问题。
假如现在厂长为了扩展产品线,决定增加一种三角形面包,怎么办?如果按照现有的思路应该这样:
看出问题了,如果增加圆形的呢?这种设计就会造成子类爆炸。不但类太多不好管理,而且一旦黑面包更改了材料,所有相关的类都得修改,麻烦!
想到我们面向对象的设计的几个原则,依赖于抽象而不是实现,多用组合少用继承。
我们考虑到这个案例中有两个系列:颜色系列:黑面包和白面包;形状系列:三角形面包和长方形面包。
于是根据依赖抽象的原则至少有两个抽象类,分别是ColorBread和ShapeBread。那这两个抽象类怎样连接起来呢?利用组合,一个类另一个类的聚合。这样依赖地位就不平等了,于是我们将这两个类改名为Bread和BreadImpl:
类图应该是这样的:
根据这个类图写出代码是十分简单的:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class BreadImpl {public: virtual string shape() = 0;};class Bread {private: BreadImpl* _impl;public: void setImpl(BreadImpl* impl) { this->_impl = impl; } virtual string look() { return _impl->shape(); }}; |
从代码中可以看出Bread有一个BreadImpl类型的成员变量,并且有一个setImpl方法可以在运行时动态修改实现,这就是所谓的桥,也就是桥接模式的核心。BreadImpl有一个shape方法返回形状,而Bread类中有一个look方法返回面包的外观。
为这两个抽象类分别编写实现类。
BreadImpl的实现类:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class TriaBread : public BreadImpl {public: string shape() { return "triangle"; }};class RectBread : public BreadImpl {public: string shape() { return "rectangle"; }}; |
Bread的实现类:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class WhiteBread : public Bread{public: string look() { return Bread::look() + " White"; }};class BlackBread : public Bread{public: string look() { return Bread::look() + " Black"; }}; |
最后在main方法里这样写:
|
1
2
3
|
Bread* bread = new BlackBread;bread->setImpl(new RectBread);cout << bread->look() << endl; |
最终输出
|
1
|
rectangle Black |
如果我们要修改成三角形的只需改成:
|
1
|
bread->setImpl(new TriaBread); |
即可。可见这将抽象与它的实现分离了,这也正式Bridge模式的主要目的。
总的来说Bridge模式是十分简单的,变化也不多。不知大家有没有注意我们使用了setImpl来对实现进行设置。这里是否可以这样做还是值得商榷的,想到之前看过的抽象工厂模式,
我们完全在这里使用一个工厂来获得实例对象。另外也可以传一个参数,由Bread类根据参数信息查询对象列表来获取对象,这里又可以使用原型模式了。还有很多模式可以利用,设
计模式就是这样,每一个模式往往并不是单独使用的
最后来看看桥接模式的适用性:
- 不希望在抽象和它的实现部分之间有一个固定的绑定关系,希望在程序运行时刻实现部分应可以被选择或者切换
- 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充
- 对一个对象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译
- 相对客户完全隐藏抽象的实现部分(针对C++)
- 有许多类要生成的时候,并且可以明显感觉到可以将一个对象分解成两个部分
- 想在多个对象间共享实现
总之,Bridge模式的核心就是将抽象部分与它的实现部分分离,这其实也是为了更低的耦合而设计的。
原文链接:http://lecoding.com/articles/175.html
posted on 2013-03-05 14:14 TheKingOfKingFish 阅读(126) 评论(0) 收藏 举报
浙公网安备 33010602011771号