【问题标题】:Question about Bridge Pattern implementation关于桥接模式实现的问题
【发布时间】:2020-10-28 04:22:53
【问题描述】:

最近,我多次尝试理解桥接模式。不同的网站试图以不同的方式解释这个概念,但我开始理解这种模式——将抽象和实现解耦——允许我们进行不同类型的实现,此外,我们能够扩展我们的接口。但我只想确定一件事 - 基于以下示例:

#include <iostream>

class Device
{
protected:
    int volume_m{ 0 };
public:
    int getVolume()
    {
        return volume_m;
    }
    void setVolume(int value)
    {
        volume_m = value;
    }
};

class RemoteController
{
private:
    std::shared_ptr<Device> device_m;
public:
    RemoteController(std::shared_ptr<Device> device) : device_m(device) {}
    void volumeUp()
    {
        device_m->setVolume(device_m->getVolume()+10);
        std::cout << "Volume turned up. Current volume: " << device_m->getVolume() << '\n';
    }
    void volumeDown()
    {
        this->device_m->setVolume(this->device_m->getVolume() - 10);
        std::cout << "Volume turned down. Current volume: " << device_m->getVolume() << '\n';
    }
    
};

class TV : public Device
{

};

class Radio : public Device
{

};


int main()
{
    std::shared_ptr<Device> tv = std::make_shared<TV>();
    std::shared_ptr<RemoteController> controller = std::make_shared<RemoteController>(tv);
    controller->volumeUp();
    controller->volumeUp();
    controller->volumeUp();
}

如果我想为TVRadio 发送不同的消息怎么办?我应该在Device 中创建名为volumeUp()volumeDown() 的虚拟方法,它们将被RadioTV 继承吗?而RemoteController 只会调用这些虚方法?

【问题讨论】:

    标签: c++ design-patterns bridge


    【解决方案1】:

    是的,我相信在RadioTV对象中实现VolumeUpVolumeDown方法会更正确。因为它们可能会因这些对象而有所不同(这两个对象都不是第 10 步)。

    而且我认为最好不要在没有太多需要的情况下通过 getter 和 setter 公开你的实现。更多关于这个here

    【讨论】:

      【解决方案2】:

      我应该在Device 中创建名为volumeUp()volumeDown() 的虚拟方法,它们将被RadioTV 继承吗?而RemoteController 只会调用这些虚方法?

      是的,简而言之,桥接模式使用委托RemoteController 委托给Device 接口定义的成员函数。 TVRadio 可以覆盖 Device 的虚成员函数。

      委托是因为桥接模式依赖于组合。为了理解它为什么使用组合,让我们首先看一个没有利用桥接模式的例子。

      单类层次结构示例 - 无桥

      您有两种不同类型的设备:电视收音机。假设您有两个不同的遥控器:射频红外线控制器。然后,您总共将有四个类:RadioIRControllerRadioRFControllerTVIRControllerTVRFController。这些类将实现一个接口RemoteController,它指定了虚拟成员函数volumeUp()volumeDown(),即一个单一的层次结构(即RemoteController)。

      在这个设计中,如果您现在想要添加一种新的遥控器,例如,超声波控制器,您必须创建两个额外的类:RadioUSControllerTVUSController .如果您想添加一种新的设备,例如,家庭立体声系统,则需要创建三个额外的类:HomeStereoIRControllerHomeStereoRFController 和 @987654348 @。

      如您所见,扩展此设计很乏味。这是因为两个正交属性——设备类型和遥控器——混合在一个类层次结构中。这是切换到桥接模式的强烈动机。

      应用桥接模式

      您将单个层次结构分成两部分:ControllerDevice。这样,每个层次结构都可以相互独立地扩展。

      我们通过部分放弃继承、拥抱组合和依赖委托来做到这一点:RemoteController 引用 Device 并调用此 Device 对象上的操作。

      扩展此设计以额外支持家庭立体声系统只需要创建一个新类HomeStereo,它继承自Device。同样,扩展此设计以支持超声波控制器只需要创建一个新类USController,它继承自RemoteController。您现在可以轻松看出差异。

      【讨论】:

        猜你喜欢
        • 2020-11-01
        • 1970-01-01
        • 2015-02-15
        • 2017-10-23
        • 2011-07-21
        • 2020-09-22
        • 1970-01-01
        • 2013-07-14
        • 2011-03-20
        相关资源
        最近更新 更多