c++ 设计模式7 (Bridge 桥模式)
4.2 Bridge 桥模式
动机:
由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个变化的维度。
代码示例:
实现一个Messager,含有基本功能PlaySound,Connect等,并有PC、Mobile不同的平台实现 和 精简、完美等不同业务功能的版本
实现方法1:
Bridge1.cpp
类的个数:1 + n + m*n,数量巨大且不同类之中有大量重复
重构见方法2
class Messager{
public:
virtual void Login(string username, string password)=;
virtual void SendMessage(string message)=;
virtual void SendPicture(Image image)=; virtual void PlaySound()=;
virtual void DrawShape()=;
virtual void WriteText()=;
virtual void Connect()=; virtual ~Messager(){}
}; //平台实现 class PCMessagerBase : public Messager{
public: virtual void PlaySound(){
//**********
}
virtual void DrawShape(){
//**********
}
virtual void WriteText(){
//**********
}
virtual void Connect(){
//**********
}
}; class MobileMessagerBase : public Messager{
public: virtual void PlaySound(){
//==========
}
virtual void DrawShape(){
//==========
}
virtual void WriteText(){
//==========
}
virtual void Connect(){
//==========
}
}; //业务抽象 class PCMessagerLite : public PCMessagerBase {
public: virtual void Login(string username, string password){ PCMessagerBase::Connect();
//........
}
virtual void SendMessage(string message){ PCMessagerBase::WriteText();
//........
}
virtual void SendPicture(Image image){ PCMessagerBase::DrawShape();
//........
}
}; class PCMessagerPerfect : public PCMessagerBase {
public: virtual void Login(string username, string password){ PCMessagerBase::PlaySound();
//********
PCMessagerBase::Connect();
//........
}
virtual void SendMessage(string message){ PCMessagerBase::PlaySound();
//********
PCMessagerBase::WriteText();
//........
}
virtual void SendPicture(Image image){ PCMessagerBase::PlaySound();
//********
PCMessagerBase::DrawShape();
//........
}
}; class MobileMessagerLite : public MobileMessagerBase {
public: virtual void Login(string username, string password){ MobileMessagerBase::Connect();
//........
}
virtual void SendMessage(string message){ MobileMessagerBase::WriteText();
//........
}
virtual void SendPicture(Image image){ MobileMessagerBase::DrawShape();
//........
}
}; class MobileMessagerPerfect : public MobileMessagerBase {
public: virtual void Login(string username, string password){ MobileMessagerBase::PlaySound();
//********
MobileMessagerBase::Connect();
//........
}
virtual void SendMessage(string message){ MobileMessagerBase::PlaySound();
//********
MobileMessagerBase::WriteText();
//........
}
virtual void SendPicture(Image image){ MobileMessagerBase::PlaySound();
//********
MobileMessagerBase::DrawShape();
//........
}
}; void Process(){
//编译时装配
Messager *m =
new MobileMessagerPerfect();
}
重构步骤:
1.继承转组合,将PCMessagerBase,Mobilemessager声明为字段;
class PCMessagerLite {
PCMessagerBase *messager;
public: virtual void Login(string username, string password){ messager -> Connect();
//........
}
virtual void SendMessage(string message){ messager -> WriteText();
//........
}
virtual void SendPicture(Image image){ messager -> DrawShape();
//........
}
}; class PCMessagerLite {
MobileMessagerBase *messager;
public: virtual void Login(string username, string password){ messager -> Connect();
//........
}
virtual void SendMessage(string message){ messager -> WriteText();
//........
}
virtual void SendPicture(Image image){ messager -> DrawShape();
//........
}
};
2.观察上述两个类,发现只有 *messager 声明不同,故采用基类声明,运行时多态调用方式,创建不同的 PCMessagerBase,Mobilemessager;
class PCMessagerLite {
Messager *messager; // = new PCMessagerBase()或 MobileMessagerBase()
public: virtual void Login(string username, string password){ messager -> Connect();
//........
}
virtual void SendMessage(string message){ messager -> WriteText();
//........
}
virtual void SendPicture(Image image){ messager -> DrawShape();
//........
}
};
3.考虑步骤2的代码,Messager类是纯虚基类(抽象类),不能实例化,故= new ...不成立。
分析产生这种状况的原因,是Login,SendPicture等与平台实现相关的方法,和PlaySound,DrawShape等与业务功能相关的方法不应该在一个类里。
将其拆分,得到MessagerImp类。
同时将MessagerLite,MessagerPerfect类中相同的MesseagerImp字段提到父类Messager,得到重构后的代码
注意运行时装配
class Messager{
protected:
MessagerImp* messagerImp;//...
public:
virtual void Login(string username, string password)=;
virtual void SendMessage(string message)=;
virtual void SendPicture(Image image)=; virtual ~Messager(){}
}; class MessagerImp{
public:
virtual void PlaySound()=;
virtual void DrawShape()=;
virtual void WriteText()=;
virtual void Connect()=; virtual MessagerImp(){}
}; //平台实现 n
class PCMessagerImp : public MessagerImp{
public: virtual void PlaySound(){
//**********
}
virtual void DrawShape(){
//**********
}
virtual void WriteText(){
//**********
}
virtual void Connect(){
//**********
}
}; class MobileMessagerImp : public MessagerImp{
public: virtual void PlaySound(){
//==========
}
virtual void DrawShape(){
//==========
}
virtual void WriteText(){
//==========
}
virtual void Connect(){
//==========
}
}; //业务抽象 m //类的数目:1+n+m class MessagerLite :public Messager { public: virtual void Login(string username, string password){ messagerImp->Connect();
//........
}
virtual void SendMessage(string message){ messagerImp->WriteText();
//........
}
virtual void SendPicture(Image image){ messagerImp->DrawShape();
//........
}
}; class MessagerPerfect :public Messager { public: virtual void Login(string username, string password){ messagerImp->PlaySound();
//********
messagerImp->Connect();
//........
}
virtual void SendMessage(string message){ messagerImp->PlaySound();
//********
messagerImp->WriteText();
//........
}
virtual void SendPicture(Image image){ messagerImp->PlaySound();
//********
messagerImp->DrawShape();
//........
}
}; void Process(){
//运行时装配
MessagerImp* mImp=new PCMessagerImp();
Messager *m =new Messager(mImp);
}
模式定义:
将抽象部分(业务功能)与实现部分(平台实现)分离,使他们都可以独立地变化。
类图:
要点总结:
Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象的实现可以沿着各自的维度来变化。所谓抽象和实现研制各自维度的变化,即“子类化”他们。
Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个雷只有一个变化的原因),复用性较差。Bridge模式是比多继承更好的解决方案。
Bridge模式的应用一般在“两个非常强的变化维度”有时一个类也有多余两个的变化维度,这是可以使用Bridge的扩展模式。
c++ 设计模式7 (Bridge 桥模式)的更多相关文章
- 设计模式 - Bridge 桥模式
Bridge桥模式也属于"的单一职责"模式中的典型模式.问题描述:我们绘制图形时,图形可以有不同形状以及不同颜色,比如圆形可以是红的,绿的,方形可以是红的绿的,如果用代码来描绘这些 ...
- Bridge 桥模式
之前一直以为桥是简单地沟通几个不同接口,使之能够按照一定流程工作.但重新查了一下解释,才有新解. 对于同一个产品的不同影响因子,如果使用继承的话,则这些影响因子则会按照M1*M2* ... Mn的数量 ...
- 设计模式(7)--Bridge(桥接模式)--结构型
1.模式定义: 桥接模式是对象的结构模式.又称为柄体(Handle and Body)模式或接口(Interface)模式.桥接模式的用意是“将抽象化(Abstraction)与实现化(Impleme ...
- C++设计模式 之 “单一职责”模式:Decorator、Bridge
part 1 “单一职责”模式 在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式 Decorato ...
- 面向对象设计模式纵横谈:Bridge 桥接模式(笔记记录)
桥接模式是一个比较难理解的设计模式,设计和分析的时候也不容易把握,咱们听听“李建忠”老师是怎么来讲的.我们还是从演变的角度来说问题,一步一步的来把问题说清楚.先谈谈“抽象”和“实现”的关系. 抽象与实 ...
- Java设计模式(6)桥模式(Bridge模式)
Bridge定义:将抽象和行为划分开来,各自独立,但能动态的结合. 为什么使用桥模式 通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以 ...
- 设计模式---单一职责模式之桥模式(Bridge)
一:概念 Bridge模式又叫做桥接模式,其实基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任他的主要特点是吧抽象与行为实现分离开来,从而可以保持各部分的独立性以及一对 ...
- C++设计模式-Bridge桥接模式
作用:将抽象部份与它的实现部份分离,使它们都可以独立地变化. 将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式 ...
- 设计模式的征途—8.桥接(Bridge)模式
在现实生活中,我们常常会用到两种或多种类型的笔,比如毛笔和蜡笔.假设我们需要大.中.小三种类型的画笔来绘制12中不同的颜色,如果我们使用蜡笔,需要准备3*12=36支.但如果使用毛笔的话,只需要提供3 ...
随机推荐
- InfiniBand
Mellanox InfiniBand卡线缆性能延迟性测试程序源码,C源码实现操作mysql库,实现简单的增删改查,代码当前用的是增插入20000条数据 具体见源码 #include <mysq ...
- Axis2在Web项目中整合Spring
一.说明: 上一篇说了Axis2与Web项目的整合(详情 :Axis2与Web项目整合)过程,如果说在Web项目中使用了Spring框架,那么又改如何进行Axis2相关的配置操作呢? 二.Axis2 ...
- 【转载】Windows/Office“神key的来源”(附win8神key)
凡是没有经过微软授权的渠道激活Windows/Office的全部是"D版"!但由于密钥激活更方便快捷,因此很受欢迎.从百度博客到现在,很多网友询问:"神key&q ...
- 购买咏南中间件送客户端C/S和B/S开发框架
购买咏南DATASNAP中间件送CS插件开发框架和BS开发框架,CS.BS开发框架共享同一个中间件.价格从优! 中间件可供DELPHI6~DELPHI XE8开发的客户端调用! CS开发框架截图: B ...
- POJ3345
http://poj.org/problem?id=3345 大意: 大意是说现在有n个城市来给你投票,你需要至少拿到m个城市的赞成票.想要获得第i个城市的赞成需要花费w[i],有个条件就是某些城市是 ...
- HDU1963Investment(DP)
简单DP,题解见代码
- UVaLive 6608 Cabin Baggage (水题)
题意:给定四个数代表长宽高和重,问你是不是满足下面条件,长不高于56,宽不宽于45,高不高于25,或者总和不大于125,并且重量不高于7. 析:判断输出就好,注意这个题是或,不要想错了. 代码如下: ...
- How Tomcat Works(十六)
本文接下来会介绍Host容器和Engine容器,在tomcat的实际部署中,总是会使用一个Host容器:本文介绍Host接口和Engine接口及其相关类 Host容器是org.apache.catal ...
- eclipse下创建maven工程
http://blog.chinaunix.net/uid-26959955-id-3248053.html
- Spring MVC体系结构
[Spring MVC类图]<Spring实战>中:<Spring3.0就这么简单>中:[http://blog.csdn.net/gstormspire/article/de ...