c++ 设计模式7 (Bridge 桥模式)
来源:互联网 发布:重大电气知乎 编辑:程序博客网 时间:2024/06/05 03:00
4.2 Bridge 桥模式
动机:
由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个变化的维度。
代码示例:
实现一个Messager,含有基本功能PlaySound,Connect等,并有PC、Mobile不同的平台实现 和 精简、完美等不同业务功能的版本
实现方法1:
Bridge1.cpp
类的个数:1 + n + m*n,数量巨大且不同类之中有大量重复
重构见方法2
1 class Messager{ 2 public: 3 virtual void Login(string username, string password)=0; 4 virtual void SendMessage(string message)=0; 5 virtual void SendPicture(Image image)=0; 6 7 virtual void PlaySound()=0; 8 virtual void DrawShape()=0; 9 virtual void WriteText()=0; 10 virtual void Connect()=0; 11 12 virtual ~Messager(){} 13 }; 14 15 16 //平台实现 17 18 class PCMessagerBase : public Messager{ 19 public: 20 21 virtual void PlaySound(){ 22 //********** 23 } 24 virtual void DrawShape(){ 25 //********** 26 } 27 virtual void WriteText(){ 28 //********** 29 } 30 virtual void Connect(){ 31 //********** 32 } 33 }; 34 35 class MobileMessagerBase : public Messager{ 36 public: 37 38 virtual void PlaySound(){ 39 //========== 40 } 41 virtual void DrawShape(){ 42 //========== 43 } 44 virtual void WriteText(){ 45 //========== 46 } 47 virtual void Connect(){ 48 //========== 49 } 50 }; 51 52 53 54 //业务抽象 55 56 class PCMessagerLite : public PCMessagerBase { 57 public: 58 59 virtual void Login(string username, string password){ 60 61 PCMessagerBase::Connect(); 62 //........ 63 } 64 virtual void SendMessage(string message){ 65 66 PCMessagerBase::WriteText(); 67 //........ 68 } 69 virtual void SendPicture(Image image){ 70 71 PCMessagerBase::DrawShape(); 72 //........ 73 } 74 }; 75 76 77 78 class PCMessagerPerfect : public PCMessagerBase { 79 public: 80 81 virtual void Login(string username, string password){ 82 83 PCMessagerBase::PlaySound(); 84 //******** 85 PCMessagerBase::Connect(); 86 //........ 87 } 88 virtual void SendMessage(string message){ 89 90 PCMessagerBase::PlaySound(); 91 //******** 92 PCMessagerBase::WriteText(); 93 //........ 94 } 95 virtual void SendPicture(Image image){ 96 97 PCMessagerBase::PlaySound(); 98 //******** 99 PCMessagerBase::DrawShape();100 //........101 }102 };103 104 105 class MobileMessagerLite : public MobileMessagerBase {106 public:107 108 virtual void Login(string username, string password){109 110 MobileMessagerBase::Connect();111 //........112 }113 virtual void SendMessage(string message){114 115 MobileMessagerBase::WriteText();116 //........117 }118 virtual void SendPicture(Image image){119 120 MobileMessagerBase::DrawShape();121 //........122 }123 };124 125 126 class MobileMessagerPerfect : public MobileMessagerBase {127 public:128 129 virtual void Login(string username, string password){130 131 MobileMessagerBase::PlaySound();132 //********133 MobileMessagerBase::Connect();134 //........135 }136 virtual void SendMessage(string message){137 138 MobileMessagerBase::PlaySound();139 //********140 MobileMessagerBase::WriteText();141 //........142 }143 virtual void SendPicture(Image image){144 145 MobileMessagerBase::PlaySound();146 //********147 MobileMessagerBase::DrawShape();148 //........149 }150 };151 152 153 void Process(){154 //编译时装配155 Messager *m =156 new MobileMessagerPerfect();157 }
重构步骤:
1.继承转组合,将PCMessagerBase,Mobilemessager声明为字段;
1 class PCMessagerLite { 2 PCMessagerBase *messager; 3 public: 4 5 virtual void Login(string username, string password){ 6 7 messager -> Connect(); 8 //........ 9 }10 virtual void SendMessage(string message){11 12 messager -> WriteText();13 //........14 }15 virtual void SendPicture(Image image){16 17 messager -> DrawShape();18 //........19 }20 };21 22 class PCMessagerLite {23 MobileMessagerBase *messager;24 public:25 26 virtual void Login(string username, string password){27 28 messager -> Connect();29 //........30 }31 virtual void SendMessage(string message){32 33 messager -> WriteText();34 //........35 }36 virtual void SendPicture(Image image){37 38 messager -> DrawShape();39 //........40 }41 };
2.观察上述两个类,发现只有 *messager 声明不同,故采用基类声明,运行时多态调用方式,创建不同的 PCMessagerBase,Mobilemessager;
1 class PCMessagerLite { 2 Messager *messager; // = new PCMessagerBase()或 MobileMessagerBase() 3 public: 4 5 virtual void Login(string username, string password){ 6 7 messager -> Connect(); 8 //........ 9 }10 virtual void SendMessage(string message){11 12 messager -> WriteText();13 //........14 }15 virtual void SendPicture(Image image){16 17 messager -> DrawShape();18 //........19 }20 };
3.考虑步骤2的代码,Messager类是纯虚基类(抽象类),不能实例化,故= new ...不成立。
分析产生这种状况的原因,是Login,SendPicture等与平台实现相关的方法,和PlaySound,DrawShape等与业务功能相关的方法不应该在一个类里。
将其拆分,得到MessagerImp类。
同时将MessagerLite,MessagerPerfect类中相同的MesseagerImp字段提到父类Messager,得到重构后的代码
注意运行时装配
1 class Messager{ 2 protected: 3 MessagerImp* messagerImp;//... 4 public: 5 virtual void Login(string username, string password)=0; 6 virtual void SendMessage(string message)=0; 7 virtual void SendPicture(Image image)=0; 8 9 virtual ~Messager(){} 10 }; 11 12 class MessagerImp{ 13 public: 14 virtual void PlaySound()=0; 15 virtual void DrawShape()=0; 16 virtual void WriteText()=0; 17 virtual void Connect()=0; 18 19 virtual MessagerImp(){} 20 }; 21 22 23 //平台实现 n 24 class PCMessagerImp : public MessagerImp{ 25 public: 26 27 virtual void PlaySound(){ 28 //********** 29 } 30 virtual void DrawShape(){ 31 //********** 32 } 33 virtual void WriteText(){ 34 //********** 35 } 36 virtual void Connect(){ 37 //********** 38 } 39 }; 40 41 class MobileMessagerImp : public MessagerImp{ 42 public: 43 44 virtual void PlaySound(){ 45 //========== 46 } 47 virtual void DrawShape(){ 48 //========== 49 } 50 virtual void WriteText(){ 51 //========== 52 } 53 virtual void Connect(){ 54 //========== 55 } 56 }; 57 58 59 60 //业务抽象 m 61 62 //类的数目:1+n+m 63 64 class MessagerLite :public Messager { 65 66 67 public: 68 69 virtual void Login(string username, string password){ 70 71 messagerImp->Connect(); 72 //........ 73 } 74 virtual void SendMessage(string message){ 75 76 messagerImp->WriteText(); 77 //........ 78 } 79 virtual void SendPicture(Image image){ 80 81 messagerImp->DrawShape(); 82 //........ 83 } 84 }; 85 86 87 88 class MessagerPerfect :public Messager { 89 90 91 public: 92 93 virtual void Login(string username, string password){ 94 95 messagerImp->PlaySound(); 96 //******** 97 messagerImp->Connect(); 98 //........ 99 }100 virtual void SendMessage(string message){101 102 messagerImp->PlaySound();103 //********104 messagerImp->WriteText();105 //........106 }107 virtual void SendPicture(Image image){108 109 messagerImp->PlaySound();110 //********111 messagerImp->DrawShape();112 //........113 }114 };115 116 117 118 119 void Process(){120 //运行时装配121 MessagerImp* mImp=new PCMessagerImp();122 Messager *m =new Messager(mImp);123 }
模式定义:
将抽象部分(业务功能)与实现部分(平台实现)分离,使他们都可以独立地变化。
类图:
要点总结:
Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象的实现可以沿着各自的维度来变化。所谓抽象和实现研制各自维度的变化,即“子类化”他们。
Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个雷只有一个变化的原因),复用性较差。Bridge模式是比多继承更好的解决方案。
Bridge模式的应用一般在“两个非常强的变化维度”有时一个类也有多余两个的变化维度,这是可以使用Bridge的扩展模式。
- (7)设计模式:bridge
- 设计模式7 - 桥接模式Bridge
- 设计模式(7) 桥接模式(BRIDGE)
- 设计模式之Bridge(桥模式)
- 设计模式:桥接模式(Bridge)
- 设计模式:桥接模式(Bridge)
- 设计模式:桥接模式(Bridge)
- 设计模式:桥接模式(Bridge)
- 【设计模式】桥接模式(Bridge)
- Bridge模式详解--设计模式(7)
- 【7】设计模式之桥模式(Bridge)
- c++ 设计模式7 (Bridge 桥模式)
- 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)
- 设计模式(c++)笔记之六(Bridge模式)
- 设计模式之 Bridge 模式(桥接模式)
- 每天一个(设计模式)-- Bridge模式(桥接模式)
- 设计模式----Bridge模式
- 设计模式:Bridge模式
- URL的#号
- c++ 设计模式9 (Abstract Factory 抽象工厂模式)
- 梯度下降法
- win10将有毛玻璃
- c++ 设计模式8 (Factory Method 工厂方法)
- c++ 设计模式7 (Bridge 桥模式)
- 利用CVX工具箱实现单快拍的稀疏矩阵DOA估计
- CG中的几何学——坐标系【2】
- c++ 设计模式6 (Decorator 装饰模式)
- android 解析json
- Android布局的基本概念及布局的运用?
- 51NOD 1434 区间LCM
- C语言再学习 -- 常用头文件和函数
- 《正则表达式》