bridge模式简要介绍(doc 18页).doc_第1页
bridge模式简要介绍(doc 18页).doc_第2页
bridge模式简要介绍(doc 18页).doc_第3页
bridge模式简要介绍(doc 18页).doc_第4页
bridge模式简要介绍(doc 18页).doc_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、bridge模式1. 问题 总结面向对象实际上就两句话:一是松耦合(Coupling),二是高内聚(Cohesion)。面向对象系统追求的目标就是尽可能地提高系统模块内部的内聚(Cohesion)、尽可能降低模块间的耦合(Coupling)。然而这也是面向对象设计过程中最为难把握的部分,大家肯定在OO系统的开发过程中遇到这样的问题:1)客户给了你一个需求,于是使用一个类来实现(A);2)客户需求变化,有两个算法实现功能,于是改变设计,我们通过一个抽象的基类,再定义两个具体类实现两个不同的算法(A1和A2);3)客户又告诉我们说对于不同的操作系统,于是再抽象一个层次,作为一个抽象基类A0,在分别

2、为每个操作系统派生具体类(A00和A01,其中A00表示原来的类A)实现不同操作系统上的客户需求,这样我们就有了一共4个类。4)可能用户的需求又有变化,比如说又有了一种新的算法.5)我们陷入了一个需求变化的郁闷当中,也因此带来了类的迅速膨胀。Bridge模式则正是解决了这类问题。2. 模式选择Bridge模式典型的结构图为: 在Bridge模式的结构图中可以看到,系统被分为两个相对独立的部分,左边是抽象部分,右边是实现部分,这两个部分可以互相独立地进行修改:例如上面问题中的客户需求变化,当用户需求需要从Abstraction派生一个具体子类时候,并不需要像上面通过继承方式实现时候需要添加子类A

3、1和A2了。另外当上面问题中由于算法添加也只用改变右边实现(添加一个具体化子类),而右边不用在变化,也不用添加具体子类了。 一切都变得elegant!view plaincopy to clipboardprint?/* * 作者:一雨田(/dylgsy/) * * Bridge模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。 * 这句话真是很晦涩,我来解释一下。所谓的实现部分,你可以想象成一个功能库,这个库是用类来组织的, * 并且实现了你需要的功能,而抽象部分就是使用这个库的类。 * 让他们独立变化的意思就是说,库增加或者使用库的代码改变都

4、是在两边独立变化的,不影响另一边 * 就好像隔了个桥梁一样,如果你理解了,就会觉得BRIDGE这个名字改得真好。 * 好了,如果不明白也没关系,先看看下面的代码。应该能明白的 */ /* * 任务叙述:我们现在要实现一个画图系统,这个系统的需求暂时来说有以下几个: * 1、画圆、画长方形。(先实现画这两个形状) * 2、已经有两个画图库了,这些画图库中定义了我们需要的操作,我们没必要重新去实现了 * 3、我们的系统能够决定使用哪个的画图库中的操作 * 根据以上的需求,我们的代码设计如下(这里先不使用Bridge模式,以便对比) : */ /* * 注意,这里使用了个预编译宏 _BRIDGE_M

5、ODE 来隔开使用Bridge和不使用Bridge两块代码。可以以这个来做分界对比看 * 两部分的代码 */ #include #include using namespace std; / 把这里注释掉就是不使用Bridge模式的代码 #define _BRIDGE_MODE / 画图库1 class CDrawLib1 public: void DrawCircle() cout 画圆操作1 endl; void DrawRectangle() cout 画长方形操作1 endl; void DrawTriangle() cout 画三角形操作1 endl; ; / 画图库2 class

6、CDrawLib2 public: void DrawCircle() cout 画圆操作2 endl; void DrawRectangle() cout 画长方形操作2 endl; void DrawTriangle() cout 画三角形操作2 endl; ; / 只要声明 _BRIDGE_MODE 就可以在使用或者不使用Bridge模式间切换了 #ifndef _BRIDGE_MODE/不使用桥模式代码 / 看到形状,很容易想到经典的Shape抽象类,并定义一个Draw接口 / 这里1代表使用画图库1的画图操作 class CShape1 public: virtual void Dr

7、aw() = 0; protected: CDrawLib1 _drawLib; ; / 画圆和画长方形,好,这里就派生出两个形状 class CCircle1: public CShape1 public: / 实现Draw操作,使用画图库1 virtual void Draw() / 使用画图库1 _drawLib.DrawCircle(); ; class CRectangle1: public CShape1 public: / 实现Draw操作,但是要使用画图库1 virtual void Draw() / 使用画图库1 _drawLib.DrawRectangle(); ; / 再

8、定义使用画图库2的Shape class CShape2 public: virtual void Draw() = 0; protected: CDrawLib2 _drawLib; ; / 画圆和画长方形,好,这里就派生出两个形状 class CCircle2: public CShape2 public: / 实现Draw操作,使用画图库2 virtual void Draw() / 使用画图库2 _drawLib.DrawCircle(); ; class CRectangle2: public CShape2 public: / 实现Draw操作,但是要使用画图库2 virtual

9、void Draw() / 使用画图库2 _drawLib.DrawRectangle(); ; void Draw1(CShape1 &s) s.Draw(); void Draw2(CShape2 &s) s.Draw(); / 好了,我们开始使用上面的类来实现我们的画图系统 void main() cout 不使用Bridge模式 DrawCircle(); ; class CRectangle: public CShape public: CRectangle(CShapeImp *imp) _sImp = imp; virtual void Draw() _sImp-DrawRect

10、angle(); ; / 好了,我们利用上面的类结构来实现我们的画图系统 void main() cout 使用Bridge模式 endl; CShapeImp1 sImp1; CShapeImp2 sImp2; / 使用画图库1 CCircle c1(&sImp1); CRectangle r1(&sImp1); c1.Draw(); r1.Draw(); / 使用画图库2 CCircle c2(&sImp2); CRectangle r2(&sImp2); c2.Draw(); r2.Draw(); /* * 好的,上述的代码运行正常,并且维护也方便了,回想一下上面的两个新需求: * 1、

11、出现了第三个库 * 2、画图系统需要画三角形 * 考虑一下,对于第一个需求,我们只需要再增加一个ShapeImp就可以了。 * 再看第二个需求,我们也是只需要派生一个CTriangle就可以了 * 可以看出来,变化不再造成混乱,只需要单独针对变化改动代码就行了。 * 也就是,变化被Bridge给分开了。 */ /* * 对于这个的模式学习,个人推荐自己写写代码,感受一下使用Bridge和不使用的前后差别, * 应该也会很快搞定它的。 */ #endif /* 作者:一雨田(/dylgsy/)* Bridge模式:将抽象部分与它的实现部分分离,使它们都可以独

12、立地变化。* 这句话真是很晦涩,我来解释一下。所谓的实现部分,你可以想象成一个功能库,这个库是用类来组织的,* 并且实现了你需要的功能,而抽象部分就是使用这个库的类。* 让他们独立变化的意思就是说,库增加或者使用库的代码改变都是在两边独立变化的,不影响另一边* 就好像隔了个桥梁一样,如果你理解了,就会觉得BRIDGE这个名字改得真好。* 好了,如果不明白也没关系,先看看下面的代码。应该能明白的*/* 任务叙述:我们现在要实现一个画图系统,这个系统的需求暂时来说有以下几个:* 1、画圆、画长方形。(先实现画这两个形状) * 2、已经有两个画图库了,这些画图库中定义了我们需要的操作,我们没必要重新

13、去实现了* 3、我们的系统能够决定使用哪个的画图库中的操作* 根据以上的需求,我们的代码设计如下(这里先不使用Bridge模式,以便对比) :*/* 注意,这里使用了个预编译宏 _BRIDGE_MODE 来隔开使用Bridge和不使用Bridge两块代码。可以以这个来做分界对比看* 两部分的代码*/#include #include using namespace std;/ 把这里注释掉就是不使用Bridge模式的代码#define _BRIDGE_MODE/ 画图库1class CDrawLib1public:void DrawCircle()cout 画圆操作1 endl;void Dr

14、awRectangle()cout 画长方形操作1 endl;void DrawTriangle()cout 画三角形操作1 endl;/ 画图库2class CDrawLib2public:void DrawCircle()cout 画圆操作2 endl;void DrawRectangle()cout 画长方形操作2 endl;void DrawTriangle()cout 画三角形操作2 endl;/ 只要声明 _BRIDGE_MODE 就可以在使用或者不使用Bridge模式间切换了#ifndef _BRIDGE_MODE/不使用桥模式代码/ 看到形状,很容易想到经典的Shape抽象类,

15、并定义一个Draw接口/ 这里1代表使用画图库1的画图操作class CShape1public:virtual void Draw() = 0;protected:CDrawLib1 _drawLib;/ 画圆和画长方形,好,这里就派生出两个形状class CCircle1: public CShape1public:/ 实现Draw操作,使用画图库1virtual void Draw()/ 使用画图库1_drawLib.DrawCircle();class CRectangle1: public CShape1public:/ 实现Draw操作,但是要使用画图库1virtual void

16、Draw()/ 使用画图库1_drawLib.DrawRectangle();/ 再定义使用画图库2的Shapeclass CShape2public:virtual void Draw() = 0;protected:CDrawLib2 _drawLib;/ 画圆和画长方形,好,这里就派生出两个形状class CCircle2: public CShape2public:/ 实现Draw操作,使用画图库2virtual void Draw()/ 使用画图库2_drawLib.DrawCircle();class CRectangle2: public CShape2public:/ 实现Dr

17、aw操作,但是要使用画图库2virtual void Draw()/ 使用画图库2_drawLib.DrawRectangle();void Draw1(CShape1 &s)s.Draw();void Draw2(CShape2 &s)s.Draw();/ 好了,我们开始使用上面的类来实现我们的画图系统void main()cout 不使用Bridge模式 DrawCircle();class CRectangle: public CShapepublic:CRectangle(CShapeImp *imp)_sImp = imp;virtual void Draw()_sImp-DrawR

18、ectangle();/ 好了,我们利用上面的类结构来实现我们的画图系统void main()cout 使用Bridge模式 endl;CShapeImp1 sImp1;CShapeImp2 sImp2;/ 使用画图库1CCircle c1(&sImp1);CRectangle r1(&sImp1);c1.Draw();r1.Draw();/ 使用画图库2CCircle c2(&sImp2);CRectangle r2(&sImp2);c2.Draw();r2.Draw();/* 好的,上述的代码运行正常,并且维护也方便了,回想一下上面的两个新需求:* 1、出现了第三个库* 2、画图系统需要画

19、三角形* 考虑一下,对于第一个需求,我们只需要再增加一个ShapeImp就可以了。* 再看第二个需求,我们也是只需要派生一个CTriangle就可以了* 可以看出来,变化不再造成混乱,只需要单独针对变化改动代码就行了。* 也就是,变化被Bridge给分开了。*/* 对于这个的模式学习,个人推荐自己写写代码,感受一下使用Bridge和不使用的前后差别,* 应该也会很快搞定它的。*/#endif view plaincopy to clipboardprint?#include using namespace std; /手机软件 class HandsetSoft public: virtual

20、 void Run()=0; ; /游戏软件 class HandsetGame : public HandsetSoft public: virtual void Run() cout运行手机游戏endl; ; /通讯录软件 class HandSetAddressList : public HandsetSoft public: virtual void Run() cout手机通讯录Run(); ; /N品牌 class HandsetBrandN : public HandsetBrand public: virtual void Run() m_soft-Run(); ; /客户端 int main() HandsetBrand *brand; brand = new HandsetBrandM(); brand-SetHandsetSoft(new HandsetGame(); brand-Run(); brand-SetHandsetSoft(new

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论