C++设计模式笔记(07) - Bridge 桥模式



  • 参考课程:《C++设计模式》-李建忠
    李建忠-C++设计模式

1.动机(Motivation)

▷由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化。

▷如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?

2.模式定义

将抽象部分(业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。
             ——《设计模式:可复用面向对象软件的基础》

3.结构(Structure)

在这里插入图片描述

4.要点总结

在这里插入图片描述
▷Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。

▷Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。

▷Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。

5.《Head First 设计模式》实例的C++实现

在这里插入图片描述

1)场景

你打算彻底改革你的“极限休息室”,正为一个新的人体工学且接口友好的电视遥控器编程。你要使用好的OO技能,让所有的遥控器基于相同的抽象,而对此抽象又做出许多不同的实现一每 部不同型号的电视都有自己的遥控器实现。在这里插入图片描述

2)你的两难

你不会第一次就做对遥控器的用户界面。事实上,你希望随着可用性数据收集得越来越丰富的同时,持续改良遥控器。所以你的两难之处就在于:遥控器会改变,而电视机也会改变。你已经将用户界面抽象出来,所以可以根据不同的电视机改变它的实现。事情还不只这样,随着使用时间的增长用户会对此界面提出一-些想法,你还必须应对他们的反馈来改变抽象。所以你要如何建立-一个OO设计,能够改变实现和抽象呢?

3)为何使用桥接模式?

桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。
在这里插入图片描述
现在你有了两个层次结构,其中一个是遥控器,而另一个是平台特定的电视机实现。有了桥接的存在,你就可以独立地改变这两个层次。

4)代码
  1. 抽象-电视机(tv)
//TV.h
// 电视机,提供抽象方法

#ifndef BRIDGE_TV_H
#define BRIDGE_TV_H

class TV {

public:
    TV(void);
    virtual ~TV(void);
    virtual void on() = 0 ;
    virtual void off() = 0 ;
    virtual void tuneChannel() = 0 ;
};

#endif //BRIDGE_TV_H
//TV.cpp
#include "tv.h"
TV::TV(void)
{
}
TV::~TV() 
{
}
  1. 具体电视机-RCA电视机(RCA)
//rca.h
//RCA电视机

#ifndef BRIDGE_RCA_H
#define BRIDGE_RCA_H

#include "tv.h"
#include <iostream>

class RCA : public TV{

public:
    RCA();
    ~RCA();
    void on() override;
    void off() override;
    void tuneChannel() override;
    void print(){ std::cout << "RCA" << std::endl;}
};

#endif //BRIDGE_RCA_H
//rca.cpp

#include "rca.h"
#include <iostream>
RCA::RCA(){}
RCA::~RCA() {}

void RCA::on()
{
    std:: cout << "RCA电视机已打开" << std:: endl;
}
void RCA::off()
{
    std:: cout << "RCA电视机已关闭" << std:: endl;
}

void RCA::tuneChannel()
{
    std:: cout << "RCA电视机换频道" << std:: endl;
}
  1. 具体电视机-Sony电视机(Sony)
//Sony.h
//Sony电视机

#ifndef BRIDGE_SONY_H
#define BRIDGE_SONY_H


#include "tv.h"

class Sony : public TV{
public:
    Sony();
    ~Sony();
    void on() override;
    void off() override;
    void tuneChannel() override;
};

#endif //BRIDGE_SONY_H
//Sony.cpp

#include "sony.h"
#include <iostream>

Sony::Sony(){}
Sony::~Sony(){}

void Sony::on()
{
    std:: cout << "Sony电视机已打开" << std:: endl;
}
void Sony::off()
{
    std:: cout << "Sony电视机已关闭" << std:: endl;
}

void Sony::tuneChannel()
{
    std:: cout << "Sony电视机换频道" << std:: endl;
}
  1. 抽象概念中的遥控器,扮演抽象化角色(RemoteControl)
// remotecontrol.h
// 抽象概念中的遥控器,扮演抽象化角色
#ifndef BRIDGE_REMOTECONTROL_H
#define BRIDGE_REMOTECONTROL_H

#include "tv.h"

class RemoteControl {
protected:
    //字段
    TV* implementor;

public:
    RemoteControl();
    virtual ~RemoteControl();
    void Implementor(TV* value);       //属性
    virtual void on();  // 开电视机,这里抽象类中不再提供实现了,而是调用实现类中的实现
    virtual void off(); // 关电视机
    virtual void turneChannel();  //换频道
};

#endif //BRIDGE_REMOTECONTROL_H
// remotecontrol.cpp
#include "remotecontrol.h"

RemoteControl::RemoteControl(){}
RemoteControl::~RemoteControl(){}

void RemoteControl::Implementor(TV* value)
{
    implementor = value;
}

void RemoteControl::on()
{
    implementor->on();
}

void RemoteControl::off()
{
    implementor->off();
}

void RemoteControl::turneChannel()
{
    implementor->tuneChannel();
}
  1. 具体遥控器(ConcreteRemote)
//concreteremote.h
//具体遥控器

#ifndef BRIDGE_CONCRETEREMOTE_H
#define BRIDGE_CONCRETEREMOTE_H

#include "remotecontrol.h"

class ConcreteRemote : public RemoteControl {
public:
    ConcreteRemote();
    ~ConcreteRemote();
    void turneChannel() override ;
};

#endif //BRIDGE_CONCRETEREMOTE_H
//concreteremote.cpp

#include "concreteremote.h"
#include <iostream>

ConcreteRemote::ConcreteRemote(){}
ConcreteRemote::~ConcreteRemote(){}

void ConcreteRemote::turneChannel()
{
    implementor->tuneChannel();
}

6.测试:

//main.cpp
#include <iostream>
#include "concreteremote.h"
#include "sony.h"
#include "rca.h"

int main() {
    // 创建一个遥控器
    RemoteControl* remoteControl = new ConcreteRemote();

    // RCA电视机
    TV* r = new RCA();
    remoteControl->Implementor(r);

    remoteControl->on();
    remoteControl->turneChannel();
    remoteControl->off();

    // Sony电视机
    TV* s = new Sony();
    remoteControl->Implementor(s);
    remoteControl->on();
    remoteControl->turneChannel();
    remoteControl->off();

    delete r;
    delete s;
    return 0;
}


欢迎关注公众号:c_302888524
发送:“设计模式:可复用面向对象软件的基础” 获取电子书
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计模式是在软件开发中常用的一种编程思想,它提供了一种解决问题的方法论,可以帮助开发者更加灵活和高效地开发软件。基于qt4开源跨平台开发框架的PDF设计模式主要包括以下几个方面。 首先,观察者模式是一种常用的设计模式,它可以用于实现PDF文件的订阅和通知功能。通过该模式,用户可以选择关注自己感兴趣的PDF文件,并在文件更新时接收到通知。 其次,工厂模式是常用的创建型设计模式,它可以帮助开发者根据需要创建不同类型的PDF文件。例如,可以使用工厂模式创建基本的PDF文件、加密的PDF文件或者带有水印的PDF文件。 再次,装饰器模式是一种结构型设计模式,可以用于在不修改现有代码的情况下为PDF文件添加额外的功能。开发者可以通过装饰器模式为PDF文件添加页眉、页脚、书签等功能,同时保持原有的PDF文件结构和功能不受影响。 此外,策略模式也是常用的设计模式之一,在PDF开发中可以用于实现不同的压缩策略和加密策略。通过策略模式,开发者可以根据需求选择不同的策略来实现对PDF文件的处理和管理。 最后,单例模式是一种创建型设计模式,可以确保在整个应用程序中只有一个PDF文件实例。通过单例模式,可以在不同的模块中共享同一个PDF文件对象,避免资源浪费和数据冲突。 总而言之,设计模式在基于qt4开源跨平台开发框架的PDF开发中具有重要的作用。以上提到的几种设计模式可以帮助开发者更好地组织和管理PDF文件,提高开发效率和代码的可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值