【设计模式】手机软件何时统一 ---- 桥接模式
一,概述
定义:将抽象部分与实现部分分离,使它们都可以独立的变化。
在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。
【注意】C++中继承声明为 public
二,示例
两款手机,品牌M和品牌N,且每部手机都包含通讯录和游戏。
1)第一种实现
实现:
以手机品牌为抽象基类,手机品牌M、N继承手机品牌基类。
再分别实现M、N中的游戏和通讯录类。
最后用爷爷类:手机品牌, 创建孙子类通讯录M(N)和游戏M(N)
缺点:
如果再增加一个MP3类则需要在手机M 和手机N下面各自加一个子类(相似的子类)
如果添加一个手机品牌则需要添加更多的类
#include <iostream> using namespace std; //手机品牌 class HandsetBrand { public: virtual void Run() { } }; //手机品牌M class HandsetBrandM : public HandsetBrand { }; //手机品牌N class HandsetBrandN : public HandsetBrand { }; //手机品牌M的游戏 class HandsetBrandMGame : public HandsetBrandM { public: void Run() { cout<<"运行M品牌手机游戏"<<endl; } }; //手机品牌N的游戏 class HandsetBrandNGame : public HandsetBrandN { public: void Run() { cout<<"运行N品牌手机游戏"<<endl; } }; //手机品牌M的通讯录 class HandsetBrandMAddressList :public HandsetBrandM { public: void Run() { cout<<"运行M品牌手机通讯录"<<endl; } }; //手机品牌N的通讯录 class HandsetBrandNAddressList : public HandsetBrandN { public: void Run() { cout<<"运行N品牌手机通讯录"<<endl; } }; int main() { HandsetBrand *ab; ab = new HandsetBrandMAddressList(); ab->Run(); ab = new HandsetBrandMGame(); ab->Run(); ab = new HandsetBrandNAddressList(); ab->Run(); ab = new HandsetBrandNGame(); ab->Run(); }
合成/聚合复用原则:尽量使用合成/聚合,尽量不要使用类继承。
聚合:表示一种“弱”的拥有关系,A对象可以包含B对象,但B对象不是A对象的一部分;大雁和大雁群的关系
合成:表示一种"强"的拥有关系,体现严格的整体和部分关系,且声明周期一样。大雁翅膀和大雁
类被封装后,被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为庞然大物。
2)另一种程序
将手机软件作为基类,让通讯录和游戏继承手机软件。然后不同手机品牌分别继承各自功能。
缺点:增加手机功能,或者是增加手机牌子都会有较大的改动。
#include <iostream> using namespace std; //手机软件 class HandsetSoft { public: virtual void Run() { } }; //通讯录 class HandsetAddressList : public HandsetSoft { }; //游戏 class HandsetGame : public HandsetSoft { }; //手机品牌M的游戏 class HandsetBrandMGame : public HandsetGame { public: void Run() { cout<<"运行M品牌手机游戏"<<endl; } }; //手机品牌N的游戏 class HandsetBrandNGame : public HandsetGame { public: void Run() { cout<<"运行N品牌手机游戏"<<endl; } }; //手机品牌M的通讯录 class HandsetBrandMAddressList : public HandsetAddressList { public: void Run() { cout<<"运行M品牌手机通讯录"<<endl; } }; //手机品牌N的通讯录 class HandsetBrandNAddressList : public HandsetAddressList { public: void Run() { cout<<"运行N品牌手机通讯录"<<endl; } }; int main() { HandsetSoft *ab; ab = new HandsetBrandMGame(); ab->Run(); ab = new HandsetBrandNGame(); ab->Run(); ab = new HandsetBrandMAddressList(); ab->Run(); ab = new HandsetBrandNAddressList(); ab->Run(); }
3)松耦合的程序
手机品牌为抽象类,包含各个品牌的具体类。
手机软件为抽嫌累,包含通讯录、游戏等
手机软件作为手机品牌的一个成员方法从而构成手机
#include <iostream> using namespace std; //手机软件 class HandsetSoft { public: virtual void Run()//;//虚函数实现多态 (必须有定义也有实现) { } }; //手机游戏 class HandsetGame :public HandsetSoft { public: void Run() { cout<<"运行手机游戏"<<endl; } }; //手机通讯录 class HandsetAddressList :public HandsetSoft { public: void Run() { cout<<"运行手机通讯录"<<endl; } }; //手机MP3播放 class HandsetMP3 :public HandsetSoft { public: void Run() { cout<<"运行手机MP3播放"<<endl; } }; //手机品牌 class HandsetBrand { protected: HandsetSoft *soft; //设置手机软件 public: void SetHandsetSoft(HandsetSoft *sof) { this->soft = sof; } //运行 virtual void Run() //虚函数 { } }; //手机品牌N class HandsetBrandN : public HandsetBrand { public: void Run() { soft->Run(); } }; //手机品牌M class HandsetBrandM :public HandsetBrand { public: void Run() { soft->Run(); } }; //手机品牌S class HandsetBrandS :public HandsetBrand { public: void Run() { soft->Run(); } }; int main() { HandsetBrand *ab; ab = new HandsetBrandN(); ab->SetHandsetSoft(new HandsetGame()); ab->Run(); ab->SetHandsetSoft(new HandsetAddressList()); ab->Run(); ab = new HandsetBrandM(); ab->SetHandsetSoft(new HandsetGame()); ab->Run(); ab->SetHandsetSoft(new HandsetAddressList()); ab->Run(); }
三,桥接模式的基本代码
#include <iostream> using namespace std; class Implementor//各个小部件类(例如手机软件) { public: virtual void Operation()//多态虚函数一定要有实现(提供给虚函数表入口地址) { } }; class ConcreteImplementorA :public Implementor { public: void Operation() { cout<<"具体实现A的方法执行"<<endl; } }; class ConcreteImplementorB :public Implementor { public: void Operation() { cout<<"具体实现B的方法执行"<<endl; } }; class Abstraction //总的构成(类似手机品牌抽象类) { protected: Implementor *implementor; public: void SetImplementor(Implementor *implementor) { this->implementor = implementor; } virtual void Operation() { implementor->Operation(); } }; class RefinedAbstraction :public Abstraction { public: void Operation() { implementor->Operation(); } }; int main() { Abstraction *ab = new RefinedAbstraction(); ab->SetImplementor(new ConcreteImplementorA());//组合A到整体中 ab->Operation(); ab->SetImplementor(new ConcreteImplementorB());//组合B到整体中 ab->Operation(); system("pause"); }