- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我最近在某个论坛上看到一个面向对象的设计问题,开始考虑使用 RTTI。然而,这一定是糟糕的设计,但我想不出替代方案。这是一个简单的问题:
使用 OO 概念为以下场景创建 C++ 程序 -
My dog, named Buddy, lives in the backyard. He barks at night when he sees a cat or a squirrel that has come to visit. If he sees a frog, and he is hungry, he eats it. If he sees a frog and he isn't hungry, he plays with it. If he has eaten 2 frogs already, and is still hungry, he will let it go. If he sees a coyote, he crys for help. Sometime his friend Spot stops by, and they chase each other. If he sees any other animal, he simply watches it. I would expect that you would have an animal class, and a cat, dog, squirrel, coyote class that inherits from the animal class.
我开始考虑在 dog 类中使用一个 see() 方法,它接受一个 Animal 参数,然后检查对象的实际类型( Frog 、猫等)并采取所需的行动——玩耍、追逐等,具体取决于实际类型。然而,这将需要 RTTI,这一定是糟糕的设计。任何人都可以提出一个更好的设计来避免 RTTI 并指出我的想法中的错误吗?
最佳答案
根据您想要强调的内容,使用“OO 概念”可以通过多种方式来解决此问题。
这是我能想到的最简单的解决方案:
class Animal {
public:
virtual void seenBy(Buddy&) = 0;
};
class Buddy {
public:
void see(Cat&) { /* ... */ }
void see(Squirrel&) { /* ... */ }
// ...
};
class Cat : public Animal {
public:
virtual seenBy(Buddy& b) { b.see(*this); }
};
class Squirrel : public Animal {
public:
virtual seenBy(Buddy& b) { b.see(*this); }
};
// classes for Frog, Coyote, Spot...
如果您需要多种“感知”动物,可以直接为 see
制作一个虚拟包装器(生成 double dispatch 的形式):
// On a parent class
virtual void see(Animal&) = 0;
// On Buddy
virtual void see(Animal& a) { a.seenBy(*this); }
以上要求 Animal
类了解 Buddy
类。如果您不喜欢您的方法是被动动词,并且想将 Animal
与 Buddy
分离,您可以使用访问者模式:
class Animal {
public:
virtual void visit(Visitor&) = 0;
};
class Cat : public Animal {
public:
virtual void visit(Visitor& v) { v.visit(*this); }
};
class Squirrel : public Animal {
public:
virtual void visit(Visitor& v) { v.visit(*this); }
};
// classes for Frog, Coyote, Spot...
class Visitor {
public:
virtual void visit(Cat&) = 0;
virtual void visit(Squirrel&) = 0;
// ...
};
class BuddyVision : public Visitor {
public:
virtual void visit(Cat&) { /* ... */ }
virtual void visit(Squirrel&) { /* ... */ }
// ...
};
class Buddy {
public:
void see(Animal& a) {
BuddyVision visitor;
a.visit(visitor);
}
};
第二种机制可以用于 Buddy 看到动物以外的目的(可能是为了让动物看到 Buddy)。然而,它更复杂。
请注意,OO 绝对不是解决此问题的唯一方法。存在可能更适用于此问题的其他解决方案,例如存储导致 Buddy 吠叫、进食、玩耍等的各种动物的属性。这另外将 Buddy
类与 Animal
类(即使是访客模式也需要 Buddy 可以感知的所有内容的详尽列表)。
关于c++ - 在 OO 设计中避免 RTTI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9287357/
我相信 OO,但不至于应该使用不适当的设计/实现来实现“OO 兼容”。 那么,如何应对 Serlvet/EJB/DataContainer 分层架构: Servlet 接收请求并调用“业务层”(例如
我有一个员工分为两类(国内和国际)。我还有一个类Refund,是用来给员工退款的。我有一个名为银行账户的类,由 Refund 类用于退款。 现在我的直接设计是这样的: 员工界面,分国内和国际2个子类型
为什么基于类的 OO 而不是基于原型(prototype)的 OO 如此受欢迎?他们在学校教后者吗?尽管 Javascript 是基于原型(prototype)的,但大多数人主要在功能上使用它,或者通
为什么基于类的 OO 而不是基于原型(prototype)的 OO 如此受欢迎?他们在学校教后者吗?尽管 Javascript 是基于原型(prototype)的,但大多数人主要在功能上使用它,或者通
我找不到主要区别。我很困惑什么时候可以使用继承,什么时候可以使用子类型。我找到了一些定义,但它们不是很清楚。 在面向对象编程中,子类型化和继承有什么区别? 最佳答案 除了已经给出的答案,这里还有一个
我想在类中动态定义方法。我正在写一个跟踪器,比下面的框架稍微复杂一些,它也有状态意识,但这与我的问题无关。我写了一个 TraceSlave 类,它带有调用 sprintf 的跟踪方法,用文本\n 替换
如果你看过Going Deep shows of the Channel9最近,一个经常被提及的话题是mathematical duality在编程中。 TomasP 有一个不错的blog post关
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我是软件设计原则的忠实粉丝,例如 固体 和 干 .面向对象软件设计还有哪些其他原则? 笔记。我不是在寻找诸如“评论您的代码”之类的答案,而是在寻找 OO 设计原则,例如 Uncle Bob 讨论的那些
我找不到主要区别。我很困惑什么时候可以使用继承,什么时候可以使用子类型。我找到了一些定义,但它们不是很清楚。 面向对象编程中的子类型和继承有什么区别? 最佳答案 除了已经给出的答案,这里还有一个 li
这个问题已经有答案了: Javascript: Do I need to put this.var for every variable in an object? (6 个回答) 已关闭 9 年前。
我正在构建一个应用程序,该应用程序在一个对象内有一个对象数组,而它的自身位于一个数组中。我希望能够从子对象访问父对象的属性。我知道我可以简单地通过索引引用父级,如下所示: var parents =
我有一个像这样的html页面 和 2 个像这样的 JavaScript 文件 /// /// /// $(document).ready(fu
我正在尝试用 javascript 做一个巨大的 Web 应用程序,如果我不想搞乱一切,我想我必须以面向对象的方式来做。因此,我进行了很多搜索,发现了很多在 JS 中声明类和创建实例的不同方法,例如环
我在理解 OO 模式如何工作时遇到了一些问题,我的讲师给了我以下问题,但我思考了一整天后无法解决它 我的问题的场景。 有一个名为“ShapeManager”的类,用于管理 Shape 对象。名为“Sh
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它. 1年前关闭。 Improve this
我正在阅读科学 paper关于 Robert martin 编写的 OO Design Quality Metrics。 在他的论文中,他描述了“一组指标,可用于衡量面向对象设计的质量,根据该设计的子
我有一个与 OOP 相关的问题。我有一个界面,说: class MyInterface { public int getValue(); } 在我的项目中,这个接口(interface)由 7
是否有更好的Pythonic/面向对象方法来选择在运行时执行哪个特定类方法,具体取决于对象的类型,因为使用 type() 方法不被认为优雅(?) 我为我正在使用的三种数据类型编写了以下代码。它基本上将
就 Perl OO 而言,-> 到底做了什么? 例如我打了一个主电话: $result = a::b->mymethod( ); 在我定义 mymethod() 的包中,我使用了以下内容: m
我是一名优秀的程序员,十分优秀!