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



以下是要考虑的层次结构

                               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对象绑定到Remote,通过我们所说的Remote Device*与之相关联Device

方法2

这是我在第一步想到的方法

DeviceRemote因此,这导致以下

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 has-a Remote(即方法 2),但是当我们实现它时,我们需要将Remote传递给 Device 构造函数中的Device,并Device传递给RemoteswitchOn()方法, 所以我们无法在Device构造函数中使用RemoteDevice的附件。如何逃脱?

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

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

请帮助决定哪种方法好?

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

我认为

,你过度解读了has-a关系:在设计一个必须相互了解的类系统时,现实世界的类比几乎没有任何作用。关键问题是,哪个对象需要访问哪些其他对象才能操纵它们/启动它们。这是一个纯粹的技术问题。

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

所以,我认为你应该说遥控器有一个它控制的设备。就这样算了。如果且仅当设备还需要与遥控器通信(不太可能),您可以添加说设备也有远程,就像您向链表添加第二个链接以形成双链表一样。但是您不应该无缘无故地添加该引用。

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

最新更新