以下是要考虑的层次结构
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;
}
上面的程序是不言自明的,我们利用了运行时多态性的优势。
在上面的程序中,我们将Television
和AirConditioner
对象绑定到Remote
,通过我们所说的Remote
Device*
与之相关联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
has-a Remote
(即方法 2),但是当我们实现它时,我们需要将Remote
传递给 Device
构造函数中的Device
,并Device
传递给Remote
的switchOn()
方法, 所以我们无法在Device
构造函数中使用Remote
和Device
的附件。如何逃脱?
那么,这里需要做什么呢?方法 2 是否比方法 1 更好?如果是,那么上述问题的解决方案是什么?如果不是,那么我如何满足自己方法1更好?
我个人认为(如果我的观点是错误的,请纠正我)Television
有Remote
比其他方法更具吸引力。
请帮助决定哪种方法好?
编辑 一个设备将用一个遥控器控制,反之亦然。
,你过度解读了has-a关系:在设计一个必须相互了解的类系统时,现实世界的类比几乎没有任何作用。关键问题是,哪个对象需要访问哪些其他对象才能操纵它们/启动它们。这是一个纯粹的技术问题。
回到您的示例:虽然设备通常只有一个与之关联的遥控器,但设备不需要知道哪些遥控器可以操作它。遥控器需要启动设备(= 调用其方法之一)。因此,遥控器需要知道其设备,而不是遥控器的设备。
所以,我认为你应该说遥控器有一个它控制的设备。就这样算了。如果且仅当设备还需要与遥控器通信(不太可能),您可以添加说设备也有远程,就像您向链表添加第二个链接以形成双链表一样。但是您不应该无缘无故地添加该引用。
一般来说,如果你让自己过多地受到现实世界类比的影响,你会得到过于复杂的设计,这是不好的。始终使用适合您需求的最简单、最直接的实现(= 遵循 KISS 原则)。无论如何,它通常是最好的。