【设计模式攻略】结构型模式之Bridge模式

概要
先考虑下在通信,电子等很多领域都常用的桥接概念,它的作用是什么?第一,它可以连接两个区域,第二,它可以隔离两个区域,简单来说也就是连接与分离的作用。而这里的 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模式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值