c++ - 在这种情况下,哪种设计模式可以很好地实现运行时多态性?

标签 c++ design-patterns polymorphism object-oriented-analysis

以下是要考虑的层次结构

                               Device
                                  ^
                                  |
                                  |
                            -------------
                            |           |
                            |           |
                       Television   AirConditioner

我们有另一个类Remote来控制设备。

方法 1

class Remote 
{    
     Device* d; 
     public:
     Remote(Device* d){
        this->d = d;
     }

     void switchOn(){ 
          d->on();
     }
     //other methods 
};


//Simple classes for concept only.

class Device
{
    public: 
       virtual void on() = 0;
};
class Television : public Device
{
    public:
       void on(){
           cout << "television is turned on";
       }
       //other methods.
};
class AirConditioner : public Device
{
    public:
        void on(){
            cout << "Ac is turned on";
        }
};

int main(){

    Device *tv = new Television();
    Device *ac = new AirConditioner();

    Remote TVremote(tv); //assigning tv to the TVremote.
    Remote ACremote(ac); //assigning ac to the ACremote.
    TVremote.switchOn();
    ACremote.switchOn();

    return 0;
 }

上面的程序是不言自明的,我们利用了运行时多态性。

在上面的程序中,我们通过Device*TelevisionAirConditioner对象绑定(bind)到Remote,即我们表示Remote has-a Device与之关联。

方法 2

这是我第一步想到的方法

设备 远程 因此,这导致以下结果

class Remote 
{    

     public:
     void switchOn(Device* d){ 
         d->on();
     }
     //other methods 
};


//Simple classes for concept only.

class Device
{
    private:
       Remote r;

    public: 
        Device(Remote* r){

              this->r = *r;
        }

       virtual void on() = 0;
};
class Television : public Device
{
    public:

       Television(Remote* r): Device(r){}
       void on(){
           cout << "television is turned on";
       }
       //other methods.
};
class AirConditioner : public Device
{
    public:
        AirConditioner(Remote* r): Device(r){}
        void on(){
            cout << "Ac is turned on";
        }
};

int main()
{
     Remote TvRemote;
     Remote AcRemote;

     Television* tv = new Television(TvRemote);
     AirConditioner* ac = new AirConditioner(AcRemote);

     TvRemote.switchOn(tv); //now we have to pass tv to the method although 
                            // Remote is of tv
     AcRemote.switchOn(ac); // same as above.


     return 0;
}

所以我有以下问题

问题 1 当我们必须对上述场景进行编程时,人脑首先想到的是电视 has-a Remote(这是方法 2),但是当我们实现它时,我们需要将 Remote 传递给 Device 构造函数中的 Device 并也将 Device 绑定(bind)到 RemoteswitchOn() 方法,因此我们无法使用 Remote 的附件和 Device 构造函数中的 Device。如何摆脱它?

那么,这里需要做什么呢?方法 2 比方法 1 更好吗?如果是,那么上述问题的解决方案是什么?如果不是,那么我如何让自己确信方法 1 更好?

我个人认为(如果我的观点错误,请纠正我)电视 has-a Remote比其他更具吸引力方法。

请帮助确定哪种方法更好?

编辑一台设备可由一个 Remote 控制,反之亦然。

最佳答案

我认为,您过度解释了“有一个”关系:在设计必须相互了解的类系统时,现实世界的类比几乎不起作用。关键问题是,哪个对象需要访问哪些其他对象才能操纵它们/让它们发挥作用。这是一个纯粹的技术问题。

回到您的示例:虽然一台设备通常只有一个与之关联的 Remote ,但该设备并不需要知道哪些 Remote 可以操作它。 Remote 需要让设备启动(= 调用其方法之一)。因此 Remote 需要知道它的设备,而不是 Remote 的设备。

所以,我认为你应该说 Remote 有一个它控制的设备。就这样吧。当且仅当设备也需要与 Remote 通信时(不太可能),您可以添加表示该设备也有 Remote ,就像您向链表添加第二个链接以形成双链表一样。链接列表。但您不应该无缘无故地添加该引用。

一般来说,如果你让自己过多地受到现实世界类比的影响,你会得到过于复杂的设计,这是不好的。始终使用适合您需求的最简单、最直接的实现(= 遵循 KISS 原则)。无论如何,它通常是最好的。

关于c++ - 在这种情况下,哪种设计模式可以很好地实现运行时多态性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38273251/

相关文章:

c++ - 在 C++ 中使用 boost::lexical_cast 将 double 转换为字符串?

C++,如何从命令行提供输入文件名,而不在程序中对其进行硬编码?

c++ - MKL 或 BLAS 例程将 vector 乘以不合适的标量

c# - 命令模式和 OnPaint 事件问题

c# - MVVM 数据访问层放在哪里?

c++ - 在 vector 中找到第一个缺失的元素

java - 直觉与设计原则

c++ - 如何在不修改uml图c++的情况下实现向对象添加价格

Java - 避免静态函数的 switch 语句

Python Child 不能使用 Parent 导入的模块