假设我正在编写一个处理一篮水果的机器人。橙子需要榨汁,苹果需要切片,香蕉需要去皮。幸运的是,我们的机器人拥有榨汁、切片和剥皮所需的精确工具。
Robot::processFruit(List<Fruit*> basket)
{
foreach(Fruit *fruit, basket)
{
if( ? ) { juiceIt(fruit); }
else if( ? ) { sliceIt(fruit); }
else if( ? ) { peelIt(fruit); }
}
}
这是我偶尔遇到的一个问题的一般示例。我有一种直觉,我的设计有问题,以至于我什至被引导到一个processFruit()
函数,因为我使用的是面向对象的语言,但它似乎没有一个干净的解决方案来解决这个问题。
我可以创建一个enum FruitType { Orange, Apple, Banana}
then require each fruits to implement virtual FruitType fruitType()
,但看来我只是在重新实现一个类型系统。
或者我可以拥有一些功能virtual bool isOrange(); virtual bool isApple(); ...
,但正如我们所看到的那样,它很快就会失控。
我也可以使用 C++ typeid
,但是这本维基书说
RTTI 只能在 C++ 程序中谨慎使用。
所以我不愿意采取这种方法。
看来我在面向对象程序的设计中一定遗漏了一些基本和关键的东西。C++ 都是关于继承和多态的,那么有没有更好的方法来解决这个问题?
process()
更新:我喜欢拥有一个所有Fruit
都需要实现的通用功能的想法。但是,如果我现在想添加一个Lemon
并想榨汁怎么办?我不想复制榨汁代码,所以我应该创建一个class Juicable : public Fruit
并同时拥有 Oranges 和 LemonsJuicable
吗?