【设计模式攻略】结构型模式之Bridge模式
来源:互联网 发布:网络推广sem 编辑:程序博客网 时间:2024/04/30 22:41
概要
先考虑下在通信,电子等很多领域都常用的桥接概念,它的作用是什么?第一,它可以连接两个区域,第二,它可以隔离两个区域,简单来说也就是连接与分离的作用。而这里的 Bridge模式也是类似,它可以分离系统的不同层次,使不同层次的实现可以相互独立的变化,同时它又为不同层次间建立起了连接进行交互。
目的
对 Bridge模式,比较教条或比较官方的定义是,可以分离抽象与实现,并使它们可以相互独立的变化。我的理解让我对常规的定义略加补充,我的观点是,它可以通过抽象与实现的分离,来分离系统中不同层次的功能,使不同层次间可以相互独立的变化。
实例
上面的说明都比较抽象,还是用实例来打动大家吧。看这样一个例子。
假设要为一个系统设计插件,首先这个系统是需要跨平台的,其次,由于插件经常会版本升级,所以系统需要支持多多个版本插件。顺着需求,我们可能会这样去考虑解决方案。
因为需要跨平台,那么通过抽象和继承来实现跨平台。
又因为每个平台都需要支持多个插件版本,那就继续在每个平台下扩展不同版本吧。
代码如下:
class IPlugin {public: virtual void LoadPlugin() = 0; virtual void UnloadPlugin() = 0; virtual void Start() = 0; virtual void Stop() = 0;};class WindowsPlugin : public IPlugin {public: virtual void LoadPlugin() { ...... } virtual void UnloadPlugin() { ...... }};class WinPluginVer1 : public WindowsPlugin {public: virtual void Start() = 0 { ...... // do something for Ver1 LoadPlugin(); } virtual void Stop() = 0 { UnloadPlugin(); ...... // do something for Ver1 }};class WinPluginVer2 : public WindowsPlugin {public: virtual void Start() = 0 { ...... // do something for Ver2 LoadPlugin(); } virtual void Stop() = 0 { UnloadPlugin(); ...... // do something for Ver2 }};
这里省略 windows以外平台, 以及 Ver1,2以外版本的代码。
以上确实是一种解决方法,但却不是一种好方法。试想一下如果现在又多出一种平台了怎么办?只能再加一个继承分支,同时对这个平台也需要追加多个版本的实现。而如果又升级了一个版本怎么办?只能在每种平台下都追加该版本的实现。类结构就膨胀成如下这样:
现在可以看出,平台和版本这系统中两个层次的实现被耦合在一起,导致每次功能追加都伴随着重复的实现和类的膨胀。很难想象,当再追加 n个平台,和 n个版本的支持后,系统结构会爆炸式的膨胀成什么样!伴随着的还有设计,编码,测试等成本以及风险的成倍增加。
怎么解决上面的问题, OK,该 Bridge模式登场了。
首先,让我们把平台和版本这两个层次间的耦合分离开来,分离出各自的抽象与实现。
class IPluginPlatform {public: virtual void LoadPlugin() = 0; virtual void UnloadPlugin() = 0;};class WindowsPlugin : public IPluginPlatform {public: virtual void LoadPlugin() { ...... } virtual void UnloadPlugin() { ...... }};class IPlugin {public: virtual void Start() = 0; virtual void Stop() = 0;};class PluginVer1 : public IPlugin {public: virtual void Start(); virtual void Stop();};
既然是 Bridge,在分离的同时也需要连接,怎么连接呢?很简单,进一步完善下 IPlugin和 PluginVer1类 ,代码如下所示:
class IPlugin {public: IPlugin(IPluginPlatform* plugin) { mPluginPF = plugin; } void LoadPlugin() { mPluginPF->LoadPlugin(); } void UnloadPlugin() { mPluginPF->UnloadPlugin(); } virtual void Start() = 0; virtual void Stop() = 0;private: IPluginPlatform* mPluginPF;};class PluginVer1 : public IPlugin {public: virtual void Start() = 0 { ...... // do something for Ver1 LoadPlugin(); } virtual void Stop() = 0 { UnloadPlugin(); ...... // do something for Ver1 }};class PluginVer2 : public IPlugin {public: virtual void Start() = 0 { ...... // do something for Ver2 LoadPlugin(); } virtual void Stop() = 0 { UnloadPlugin(); ...... // do something for Ver2 }};
IPlugin 包含了当前对应的 Plugin平台对象,通过该对象实现 LoadPlugin, UnloadPlugin方法,而在其子类中不再需要去关心到底是使用哪个平台相关对象,只需要直接通过父类 IPlugin的 LoadPlugin, UnloadPlugin方法进行插件加载卸载就可以了。
从如下类图可以更清晰的看出所谓 Bridge模式中类桥接的关系。通过 Bridge模式,分离了平台和版本这两个层次,使它们各自能够相对独立的扩展。不管是多支持一个平台还是多支持一种版本,都只需要扩展追加一个相应的类就可以实现,结构层次分明,使用也非常方便。
应用
当需要分离不同层次功能间的耦合,分离抽象与实现时,可以采用 Bridge模式。当然,前提是分析清楚真正的需求,滥用 Bridge模式也会让本来很简单清晰的应用变得既冗余又复杂。另外,可以通过 Abstract Factory模式来创建 Bridge模式中一端的具体实现(如上的 IPluginPlatform的子类对象),详细情况请参照 Abstract Factory模式。
- 【设计模式攻略】结构型模式之Bridge模式
- 设计模式之结构型模式(一)-----桥接(bridge)模式
- 译-设计模式-结构模式之Bridge
- 设计模式笔记--结构型模式之二--桥接 Bridge
- 设计模式(结构型)之桥接模式(Bridge Pattern)
- 【设计模式】结构型模式之桥接Bridge
- 【设计模式攻略】结构型模式之Adapter模式
- 【设计模式攻略】结构型模式之Composite模式
- 【设计模式攻略】结构型模式之Decorator模式
- 【设计模式攻略】结构型模式之Flyweight 模式
- 【设计模式攻略】结构型模式之Proxy模式
- 【设计模式攻略】结构型模式之Facade模式
- 设计模式-结构模式之桥梁模式Bridge
- 结构型模式之Bridge模式
- 结构模式之Bridge
- 结构模式之Bridge
- 设计模式之Bridge模式
- 设计模式之Bridge模式
- 威海涨潮退潮时间表
- 中国人均月薪4134元 拖后腿的是ILO统计数据
- 无法访问到该应用的备份接口,请拷贝 UCenter 根目录下api/dbbak.php 到该应用的api目录的问题
- hdu 1199想用线段树,结果发现不好处理,某天突然想起这方法。。易懂,不好写。。。
- AU3--获得网卡mac地址
- 【设计模式攻略】结构型模式之Bridge模式
- 寻找第K大的数的方法总结
- oracle create view 记录
- tomcat启动,访问http://localhost:8080时报http status 404
- 互联网大佬们的创业忠告
- vc显示DIB
- 斜线/、反斜线\、双斜线//、双反斜线\\
- OGNL表达式struts2标签“%,#,$”
- 使用3COM DABS撘建PXE服务器。