我怎样才能掌握纯OOD的概念
How can I grasp the concept of pure OOD?
我在理解纯OOD的概念上仍然有一点问题。
假设我们有一个类Human,我们生活在一个世界里,有时人类行走(大脑命令腿),有时树木消失(人类注意到这一点),有时人类随机地相互撞击。
前两种情况真的很简单:
class Tree {
private:
void disappear()
{
// call onTreeDisappeared() for all human observers
}
};
class Human {
public:
// The human notices that a tree disappeared
void onTreeDisappeared();
private:
int x, y, z;
// Human wants to walk forward
void moveForward();
// Hit another human, possibly causing him to fall down
void hit(Human &target);
};
现在hit方法有了一个非常严重的问题。当然,你可以用
anna.hit(bob);
在此之前,我认为它很好(如果有不好的地方请抱怨),读起来像散文(好的OOP代码应该是这样的)。但是你如何将打击转移到OOP中呢?如果安娜打了鲍勃,鲍勃摔倒了,那么摔倒既不是安娜直接造成的,也不是鲍勃直接造成的。这是由撞击、失去平衡和物理作用造成的。
我知道这种情况下只有两个选择,但不知何故,我认为这两个都很糟糕:
public: void fallDown()
{ z = 0; }
public: void hit(Human &target)
{
bool targetFallsDown = true; // could be random or any algorithm you like
if(targetFallsDown)
{ target.fallDown(); }
}
在这个例子中Anna"摔倒"了Bob。但这完全说不通。又不是安娜抓住鲍勃的身体然后把它移到地上。但是还有另一个选项:
private: void fallDown()
{ z = 0; }
public: void onHitCausesMeToFallDown()
{ fallDown(); }
public: void hit(Human &target)
{
bool targetFallsDown = true; // could be random or any algorithm you like
if(targetFallsDown)
{ target.onHitCausesMeToFallDown(); }
}
在这种情况下,Bob的身体"注意到"撞击使他摔倒在地,然后他会"移动自己"到地上。我认为这比第一个选项好,但这仍然感觉不对。
所以,聪明的OOP同学们,请给我解释一下,当在现实世界中A修改了B的状态,而在OOP世界中只有B应该修改B的状态时,你该如何处理这种情况
我认为您正在落入一个陷阱,试图在类中模拟"真实"世界,而没有为您的设计设定一个目的。
你的程序应该做什么?一旦你解决了这个问题,你就可以开始设计你想要建模的现实世界的哪些方面,以及现实世界的哪些部分不重要,不需要建模。仅仅因为容易可视化就将类映射到具体的现实世界对象类型上,这通常是一个错误。您只需要对与您的程序相关的概念进行建模。
OOD是关于使用诸如抽象和多态性之类的技术来允许对象相互交互,而不必知道彼此的实现。
在你的实现中,你需要决定你想要建模的行为和每个对象需要的知识。例如,你可能想让一个人根据他被击中的程度来计算他是否想摔倒。
void Human::receiveHit(Hit hit)
{
if (hit.IsBigForThisWeight(this->weight))
this->fallDown();
}
请注意,击中我的东西不需要知道或关心它会对我产生什么影响。这是我的反应。我还建模了一个"命中"对象,因为它对我的程序很有意义。通过创建一个Hit
对象并让我接收它,任何东西都可以击中我。在未来,我可以被公共汽车或火车撞倒,而不改变我的类。
我认为你的困境出现是因为你没有模拟时间的流逝。当你做anna.hit(bob)
时,一切都同时发生。
如果你将实体建模为运行它们自己的状态机,那么事情将开始看起来更像现实:
-
anna.hit(bob)导致bob的状态变为
falling
-
在接下来的几个周期中,bob一直处于
falling
状态。 -
最终bob的状态变为
on_ground
。 -
bob的状态变为
cries_for_mommy
查看状态设计模式,了解如何在OO语言中实现开始图表。"四人帮"的设计模式书涵盖了这个主题。