在这种情况下,哪种设计模式有利于实现运行时间多态性?

时间:2016-07-08 18:29:13

标签: 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;
 }

上述程序是自解释的,我们利用运行时多态性。

在上面的程序中,我们将TelevisionAirConditioner对象绑定到RemoteDevice*我们正在说Remote has-a Device与之相关。

方法2

这是第一步出现在我脑海中的方法

Device 有一个 Remote 所以,这导致了以下

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;
}

所以我有以下问题

Q 1 当我们必须对上述情景进行编程时,人类大脑的第一件事是Television 有一个 Remote(方法2)但是当我们实现它时,我们需要将Remote传递给Device构造函数中的Device,并Device传递给switchOn()方法Remote,因此我们无法在Remote构造函数中使用DeviceDevice的附件。如何逃脱它?

那么,这里有什么需要做的?方法2是否优于方法1?如果是,那么上述问题的解决方案是什么?如果不是那么我如何满足自己的方法1更好?

我个人认为(如果我的观点错误,请更正我)Television 有一个 Remote比其他方法更具吸引力。

请帮助决定哪种方法好?

编辑一台设备将由一台遥控器控制,反之亦然。

1 个答案:

答案 0 :(得分:2)

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

回到你的例子:虽然设备通常只有一个与之关联的遥控器,但设备不需要知道哪个遥控器可以操作它。需要将设备投入运行的遥控器(=调用其中一种方法)。因此遥控器需要知道它的设备,而不是远程设备。

所以,我认为你应该说遥控器有一个它控制的设备。并留在那。如果,并且仅当设备还需要与远程设备通话(不太可能)时,您可以添加说设备也具有 - 远程,就像您将第二个链接添加到链接列表以形成双精度链表。但是你根本不应该添加这个参考文献。

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