




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、bridge 模式1. 问题总结面向对象实际上就两句话:一是松耦合( Coupling ),二是高内聚( Cohesion )。面向对象系统追求的目标就是尽可能地提高系统模块内部的内聚( Cohesion )、尽可能降低模块间的耦合( Coupling )。然而这也是面向对象设计过程中最为难把握的部分,大家肯定在 OO 系统的开发过程中遇到这样的问题:1 )客户给了你一个需求,于是使用一个类来实现( A);2 )客户需求变化,有两个算法实现功能,于是改变设计,我们通过一个抽象的基类,再定义两个具体类实现两个不同的算法( A1 和 A2 );3 )客户又告诉我们说对于不同的操作系统,于是再抽象一
2、个层次,作为一个抽象基类 A0 ,在分别为每个操作系统派生具体类( A00 和 A01 ,其中 A00 表示原来的类 A )实现不同操作系统上的客户需求,这样我们就有了一共4 个类。4)可能用户的需求又有变化,比如说又有了一种新的算法.5 )我们陷入了一个需求变化的郁闷当中,也因此带来了类的迅速膨胀。Bridge 模式则正是解决了这类问题。2. 模式选择Bridge 模式典型的结构图为:在 Bridge 模式的结构图中可以看到,系统被分为两个相对独立的部分,左边是抽象部分,右边是实现部分,这两个部分可以互相独立地进行修改:例如上面问题中的客户需求变化,当用户需求需要从Abstraction 派
3、生一个具体子类时候,并不需要像上面通过继承方式实现时候需要添加子类A1 和 A2 了。另外当上面问题中由于算法添加也只用改变右边实现(添加一个具体化子类),而右边不用在变化,也不用添加具体子类了。一切都变得elegant !view plaincopy to clipboardprint?/* 作者:一雨田( )* Bridge 模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。* 这句话真是很晦涩,我来解释一下。所谓的实现部分,你可以想象成一个功能库,这个库是用类来组织的,并且实现了你需要的功能,而抽象部分就是使用这个库的类。* 让他们独立变化的意思就是说,库增加或者使用库的代码改
4、变都是在两边独立变化的,不影响另一边* 就好像隔了个桥梁一样,如果你理解了,就会觉得 BRIDGE 这个名字改得真好。* 好了,如果不明白也没关系,先看看下面的代码。应该能明白的* */* 任务叙述:我们现在要实现一个画图系统,这个系统的需求暂时来说有以下几个:* 1 、画圆、画长方形。 ( 先实现画这两个形状 )* 2 、已经有两个画图库了,这些画图库中定义了我们需要的操作,我们没必要重新去实现了* 3 、我们的系统能够决定使用哪个的画图库中的操作* 根据以上的需求,我们的代码设计如下( 这里先不使用 Bridge 模式,以便对比) :* */ /* * 注意,这里使用了个预编译宏以以这个来
5、做分界对比看BRIDGE_MODE 来隔开使用 Bridge 和不使用 Bridge 两块代码。可* 两部分的代码* */ #include <stdio.h>#include <iostream>using namespace std;/ 把这里注释掉就是不使用 Bridge 模式的代码#define _BRIDGE_MODE/ 画图库 1class CDrawLib1public:void DrawCircle()cout << " 画圆操作 1" << endl;void DrawRectangle()cout <
6、< " 画长方形操作 1" << endl;void DrawTriangle()cout << " 画三角形操作 1" << endl;/ 画图库 2class CDrawLib2public:void DrawCircle()cout << " 画圆操作 2" << endl;void DrawRectangle()cout << " 画长方形操作 2" << endl;void DrawTriangle()cout &l
7、t;< " 画三角形操作 2" << endl;/ 只要声明 _BRIDGE_MODE 就可以在使用或者不使用 Bridge 模式间切换了#ifndef _BRIDGE_MODE/ 不使用桥模式代码/ 看到形状,很容易想到经典的 Shape 抽象类,并定义一个Draw 接口/ 这里 1 代表使用画图库1 的画图操作class CShape1public:virtual void Draw() = 0;protected:CDrawLib1 _drawLib;/ 画圆和画长方形,好,这里就派生出两个形状class CCircle1: public CShap
8、e1public:/ 实现 Draw 操作,使用画图库1virtual void Draw()/ 使用画图库1_drawLib.DrawCircle();class CRectangle1: public CShape1public:/ 实现 Draw 操作,但是要使用画图库1virtual void Draw()/ 使用画图库1_drawLib.DrawRectangle();/ 再定义使用画图库2 的 Shapeclass CShape2public:virtual void Draw() = 0;protected:CDrawLib2 _drawLib;/ 画圆和画长方形,好,这里就派生
9、出两个形状class CCircle2: public CShape2public:/ 实现 Draw 操作,使用画图库2virtual void Draw()/ 使用画图库2_drawLib.DrawCircle();class CRectangle2: public CShape2public:/ 实现 Draw 操作,但是要使用画图库2virtual void Draw() / 使用画图库2_drawLib.DrawRectangle();void Draw1(CShape1 &s)s.Draw();void Draw2(CShape2 &s)s.Draw();/ 好了,
10、我们开始使用上面的类来实现我们的画图系统void main()cout << " 不使用 Bridge 模式 " << endl;/ 我可以使用两种库CCircle1 c1;CCircle2 c2;CRectangle1 r1;CRectangle2 r2;Draw1(c1);Draw1(r1);Draw2(c2);Draw2(r2);/* *好的,上述的代码运行正常,如果不需要维护的话,我们就不用管它拉 但是,代码是一定要维护的,逃不过的宿命。* 出现变化的地方可能是这样的:1 、出现了第三个库2 、画图系统需要画三角形* 这个时候,我们再看看要完
11、成这两个变化我们需要作的修改,就会发现,我要晕了* (当一个程序员要晕的时候,也就是BUG 要出现的时候了)* */ #else /* *好了,现在让我们使用 Bridge 模式来实现上面的系统Bridge 模式最重要是把表示和实现分开* */ / 建立一个实现操作的类: CShapeImp class CShapeImp public:virtual void DrawCircle() = 0;virtual void DrawRectangle() = 0; ;class CShapeImp1: public CShapeImp public:virtual void DrawCircle
12、()_dLib.DrawCircle();virtual void DrawRectangle()_dLib.DrawRectangle();private:CDrawLib1 _dLib;class CShapeImp2: public CShapeImppublic:virtual void DrawCircle()_dLib.DrawCircle();virtual void DrawRectangle()_dLib.DrawRectangle();private:CDrawLib2 _dLib;class CShapepublic:virtual void Draw() = 0;pro
13、tected:CShapeImp *_sImp;class CCircle: public CShapepublic:CCircle(CShapeImp *imp)_sImp = imp;virtual void Draw()_sImp->DrawCircle();class CRectangle: public CShapepublic:CRectangle(CShapeImp *imp)_sImp = imp;virtual void Draw()_sImp->DrawRectangle();/ 好了,我们利用上面的类结构来实现我们的画图系统void main()cout &l
14、t;< " 使用 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 、画图系统需要画
15、三角形* 考虑一下,对于第一个需求,我们只需要再增加一个ShapeImp 就可以了。* 再看第二个需求,我们也是只需要派生一个CTriangle 就可以了* 可以看出来,变化不再造成混乱,只需要单独针对变化改动代码就行了。* 也就是,变化被 Bridge 给分开了。* */ /* *对于这个的模式学习,个人推荐自己写写代码,感受一下使用Bridge 和不使用的前后差别,应该也会很快搞定它的。* */ #endif /* * 作者:一雨田( )*Bridge 模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。这句话真是很晦涩,我来解释一下。所谓的实现部分,你可以想象成一个功能库,这个库
16、是用类来组织 的,并且实现了你需要的功能,而抽象部分就是使用这个库的类。让他们独立变化的意思就是说,库增加或者使用库的代码改变都是在两边独立变化的,不影响另一边就好像隔了个桥梁一样,如果你理解了,就会觉得 BRIDGE 这个名字改得真好。好了,如果不明白也没关系,先看看下面的代码。应该能明白的* */ /* *任务叙述:我们现在要实现一个画图系统,这个系统的需求暂时来说有以下几个:1 、画圆、画长方形。 ( 先实现画这两个形状 )2 、已经有两个画图库了,这些画图库中定义了我们需要的操作,我们没必要重新去实现了3 、我们的系统能够决定使用哪个的画图库中的操作根据以上的需求,我们的代码设计如下(
17、 这里先不使用 Bridge 模式,以便对比) : * */ /* * 注意,这里使用了个预编译宏_BRIDGE_MODE 来隔开使用 Bridge 和不使用 Bridge 两块代码。可以以这个来做分界对比看* 两部分的代码* */#include <stdio.h>#include <iostream>using namespace std;/ 把这里注释掉就是不使用 Bridge 模式的代码#define _BRIDGE_MODE/ 画图库 1class CDrawLib1public:void DrawCircle()cout << " 画圆
18、操作 1" << endl;void DrawRectangle()cout << " 画长方形操作1" << endl;void DrawTriangle()cout << " 画三角形操作1" << endl;/ 画图库 2class CDrawLib2 public:void DrawCircle()cout << " 画圆操作 2" << endl;void DrawRectangle()cout << " 画长
19、方形操作2" << endl;void DrawTriangle()cout << " 画三角形操作2" << endl;/ 只要声明 _BRIDGE_MODE 就可以在使用或者不使用 Bridge 模式间切换了#ifndef _BRIDGE_MODE/ 不使用桥模式代码/ 看到形状,很容易想到经典的 Shape 抽象类,并定义一个Draw 接口/ 这里 1 代表使用画图库1 的画图操作class CShape1public:virtual void Draw() = 0;protected:CDrawLib1 _drawLib
20、;/ 画圆和画长方形,好,这里就派生出两个形状class CCircle1: public CShape1 public:/ 实现 Draw 操作,使用画图库1virtual void Draw()/ 使用画图库1_drawLib.DrawCircle(); class CRectangle1: public CShape1public:/ 实现 Draw 操作,但是要使用画图库1virtual void Draw() / 使用画图库1_drawLib.DrawRectangle();/ 再定义使用画图库2 的 Shapeclass CShape2public:virtual void Dra
21、w() = 0;protected:CDrawLib2 _drawLib;/ 画圆和画长方形,好,这里就派生出两个形状class CCircle2: public CShape2public:/ 实现 Draw 操作,使用画图库2virtual void Draw()/ 使用画图库2_drawLib.DrawCircle();class CRectangle2: public CShape2public:/ 实现 Draw 操作,但是要使用画图库2virtual void Draw()/ 使用画图库2_drawLib.DrawRectangle();void Draw1(CShape1 &am
22、p;s)s.Draw();void Draw2(CShape2 &s)s.Draw();/ 好了,我们开始使用上面的类来实现我们的画图系统void main()cout << " 不使用 Bridge 模式 " << endl;/ 我可以使用两种库CCircle1 c1;CCircle2 c2;CRectangle1 r1;CRectangle2 r2;Draw1(c1);Draw1(r1);Draw2(c2);Draw2(r2);/* 好的,上述的代码运行正常,如果不需要维护的话,我们就不用管它拉* 但是,代码是一定要维护的,逃不过的宿命。
23、* 出现变化的地方可能是这样的:* 1 、出现了第三个库* 2 、画图系统需要画三角形* 这个时候,我们再看看要完成这两个变化我们需要作的修改,就会发现,我要晕了* (当一个程序员要晕的时候,也就是BUG 要出现的时候了)*/#else/* 好了,现在让我们使用 Bridge 模式来实现上面的系统* Bridge 模式最重要是把表示和实现分开*/ 建立一个实现操作的类: CShapeImpclass CShapeImppublic:virtual void DrawCircle() = 0;virtual void DrawRectangle() = 0;class CShapeImp1: p
24、ublic CShapeImppublic:virtual void DrawCircle()_dLib.DrawCircle();virtual void DrawRectangle()_dLib.DrawRectangle();private:CDrawLib1 _dLib;class CShapeImp2: public CShapeImppublic:virtual void DrawCircle()_dLib.DrawCircle();virtual void DrawRectangle()_dLib.DrawRectangle();private:CDrawLib2 _dLib;c
25、lass CShapepublic:virtual void Draw() = 0;protected:CShapeImp *_sImp;class CCircle: public CShapepublic:CCircle(CShapeImp *imp)_sImp = imp;virtual void Draw()_sImp->DrawCircle();class CRectangle: public CShapepublic:CRectangle(CShapeImp *imp)_sImp = imp;virtual void Draw()_sImp->DrawRectangle(
26、);/ 好了,我们利用上面的类结构来实现我们的画图系统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();/* 好的,上述的代码运行正常,并且维
27、护也方便了,回想一下上面的两个新需求:* 1 、出现了第三个库* 2 、画图系统需要画三角形* 考虑一下,对于第一个需求,我们只需要再增加一个ShapeImp 就可以了。* 再看第二个需求,我们也是只需要派生一个CTriangle 就可以了* 可以看出来,变化不再造成混乱,只需要单独针对变化改动代码就行了。* 也就是,变化被 Bridge 给分开了。*/* 对于这个的模式学习,个人推荐自己写写代码,感受一下使用Bridge 和不使用的前后差别,* 应该也会很快搞定它的。*/#endifview plaincopy to clipboardprint?#include <iostream&
28、gt;using namespace std;/ 手机软件class HandsetSoftpublic:virtual void Run()=0;/ 游戏软件class HandsetGame : public HandsetSoftpublic:virtual void Run()cout<<" 运行手机游戏"<<endl;/ 通讯录软件class HandSetAddressList : public HandsetSoftpublic:virtual void Run()cout<<" 手机通讯录 "<&
29、lt;endl;/ 手机品牌class HandsetBrandprotected:HandsetSoft* m_soft;public:void SetHandsetSoft(HandsetSoft* temp)m_soft = temp;virtual void Run()=0;/M 品牌class HandsetBrandM : public HandsetBrand public:virtual void Run()m_soft->Run();/N 品牌class HandsetBrandN : public HandsetBrandpublic:virtual void Run
30、()m_soft->Run();/ 客户端int main()HandsetBrand *brand;brand = new HandsetBrandM();brand->SetHandsetSoft(new HandsetGame();brand->Run();brand->SetHandsetSoft(new HandSetAddressList();brand->Run();return 0;#include <iostream>using namespace std;/ 手机软件class HandsetSoftpublic:virtual void Run()=0;/ 游戏软件class HandsetGame : public HandsetSoftpublic:virtual void Run()cout<<" 运行手机游戏 "<<endl;/ 通讯录软件class HandSetAddressList : public HandsetSoftpublic:virtual void Run()cout<<" 手机通讯录"<<endl;/ 手机品牌class HandsetBrandprotected:HandsetSoft
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 课题申报书字体标准
- 合同范本美容美发
- 传媒影视合同范本
- 和移动合作合同范本
- 兼职宝洁劳务合同范本
- 含油铜轴承采购合同范例
- 知识产权保护高地建设的实践步骤与部署
- 品牌冠名合作合同范本
- 合作投资入股合同范本
- 加快建设知识产权保护高地的战略规划
- 大模型落地应用实践方案
- 售后服务组织结构及岗位职责
- 2025年鞍钢集团招聘笔试参考题库含答案解析
- 人文社科类横向课题技术服务合同5篇
- 网络工程师(软考)考试(重点)题库300题(含答案解析)
- 统编版八年级语文上册第六单元作业设计
- 中建通风与空调施工方案
- 2024-2025年江苏专转本英语历年真题(含答案)
- 永磁滚筒设备操作规程
- 2024解析:第五章透镜及其应用-讲核心(解析版)
- 《子宫肉瘤》课件
评论
0/150
提交评论