关于桥接模式实现的问题

Posted

技术标签:

【中文标题】关于桥接模式实现的问题【英文标题】: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 只会调用这些虚方法?

【问题讨论】:

【参考方案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。您现在可以轻松看出差异。

【讨论】:

以上是关于关于桥接模式实现的问题的主要内容,如果未能解决你的问题,请参考以下文章

设计模式---桥接模式

js --桥接模式

设计模式实战-桥接模式

桥接模式(Bridge Pattern)

桥接模式

设计模式:学习笔记——桥接模式