Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于桥接模式实现的问题_C++_Design Patterns_Bridge - Fatal编程技术网

C++ 关于桥接模式实现的问题

C++ 关于桥接模式实现的问题,c++,design-patterns,bridge,C++,Design Patterns,Bridge,最近,我做了几次尝试来理解桥接模式。不同的网站试图以不同的方式解释这个概念,但我开始理解这种模式——将抽象和实现解耦——允许我们进行不同类型的实现,此外,我们能够扩展我们的接口。但我只想确定一件事——基于以下示例: #include <iostream> class Device { protected: int volume_m{ 0 }; public: int getVolume() { return volume_m; }

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

#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();
}
#包括
类设备
{
受保护的:
int volume_m{0};
公众:
int getVolume()
{
返回量μm;
}
void setVolume(int值)
{
体积m=数值;
}
};
类远程控制器
{
私人:
std::共享ptr设备;
公众:
远程控制器(std::共享的ptr设备):设备(设备){
void volumeUp()
{
设备->设置卷(设备->获取卷()+10);
std::cout setVolume(this->device\u m->getVolume()-10);
std::cout volumeUp();
controller->volumeUp();
}

如果我想为
TV
Radio
制作不同的消息,我应该在
设备中创建名为
volumeUp()和
volumeDown()的虚拟方法吗
哪些将被
收音机
电视
继承?而
遥控器
只会调用这些虚拟方法?

是的,我相信在
收音机
电视
对象中实现
VolumeUp
VolumeDown
方法会更正确。因为它们可能不同对于这些对象(而不是步骤10)

我认为最好不要在没有太多需要的情况下通过getter和setter公开您的实现

我是否应该在
设备
中创建名为
volumeUp()
volumeDown()
的虚拟方法,这些虚拟方法将由
收音机
电视
继承?而
遥控器
将只调用这些虚拟方法

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

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

单类层次结构示例–无桥 你有两种不同类型的设备:电视和收音机。让我们假设你有两种不同的遥控器:射频和红外控制器。那么,你总共有四个类:
radiorcontroller
RadioRFController
TVIRController
TVRFController
。这些类将实现一个接口
RemoteController
,该接口指定虚拟成员函数
volumeUp()
volumeDown()
,即单个层次结构(即
RemoteController

在这种设计中,如果你现在想添加一种新的遥控器,例如超声波控制器,你必须创建两个额外的类:
RadioUSController
TVUSController
。如果你想添加一种新的设备,例如家庭立体声系统,那么你需要创建ree附加类:
HomeTereorController
HomeTereorFController
HomeTereousController

如您所见,扩展此设计非常繁琐。这是因为两个正交属性(设备和远程控制器的类型)混合在一个类层次结构中。这是切换到桥接模式的强烈动机

应用桥接模式 您可以将单个层次结构分为两个:
Controller
Device
。这样,每个层次结构都可以彼此独立扩展

我们通过部分地从继承切换到组合,并依赖于委托来实现:一个
远程控制器
引用一个
设备
,并调用这个
设备
对象上的操作

扩展此设计以额外支持家庭立体声系统只需要创建一个新类,
HomeStereo
,该类继承自
设备
。同样,扩展此设计以支持超声波控制器只需要创建一个新类,
USController
,该类继承自
RemoteController
。您现在可以很容易地看到其中的区别