如果我正在编写一个游戏,其中有一个工人切割木材(来自树木),我会在哪里放置“cutWood”方法,在工人阶级或树类中?
编辑: 我在OOD上读到的第一个例子是关于一个圆圈(一个叫做圆圈的类),里面有一个叫做“计算区域”的方法。 现在,确定一个圆圈不会计算自己的区域。 想到它的唯一方法是计算区域是一个与圆相关的操作(在圆上完成的操作)
因此,cutWood方法与工作者和树都相关。
答案 0 :(得分:8)
我认为工人没有采用木材切割方法的凝聚力。切割在树上完成,因此应该是树类的一部分。据推测,切割木材也将涉及改变木材类的一些内部状态。
工人应该在他想要的任何树上调用切割方法,而不是树告诉工人他应该切割它。如果你想像Hans所暗示的那样抽象出来,你可以为Cut方法创建一个ICuttable接口,让你的树实现它。
考虑一下你熟悉的事情,String
。如果要剪切字符串(拆分),则不要在每个要执行此操作的对象中定义splitString方法。无论什么对象决定拆分字符串,都会发生同样的事情 - 并且通常需要知道目标对象(字符串)的内部结构才能完成它。许多其他对象只是调用字符串的split方法。字符串对象具有高内聚力 - 因为它的方法有助于执行一项常见任务 - 操纵字符串。
我看不到切割木材对工人对象本身的贡献如何。
答案 1 :(得分:4)
问问自己:工人是砍伐木材,还是砍伐树木?
答案 2 :(得分:4)
你基本上在你的问题中回答:“一个砍柴的工人”。你应该把它放到工人阶级。
答案 3 :(得分:3)
创建
cut(Material m)
工作者提供额外面向对象的方法。
答案 4 :(得分:2)
你必须修剪树吗?
你是否必须在裁剪树时修改工人?
我想你最终会得到一个WoodCutting
服务来处理可能对这两个事件进行修改的事件,或者依次调用worker.cutWood()
和tree.woodCut()
什么是问题;)
答案 5 :(得分:2)
听起来像是战略模式的候选人。您可能需要一个带有performAction方法的WorkerAction抽象类。然后,WorkerAction类的子类将实现诸如剪切树,挖掘黄金和其他工作者操作等细节。因此,子类知道树的细节,并且可以在树上调用必要的方法来影响树被切割时的效果。
然后,worker类只需要对其调用performAction()的具体WorkerAction实例的引用。工作人员不知道树或金等的细节。这样工人可以执行操作,但您不限制工人只能执行一个操作。实际上,如果您希望将来的工作人员执行更多操作,则不再需要修改工作类。
答案 6 :(得分:1)
您可以在worker类中使用cutWood
方法,在树类中使用cutted
方法。显然,worker.cutWood
会调用tree.cutted
,这可能会返回收获的木材数量。
tree.cutted会做所有使树死亡所必需的东西。
如果您将方法调用视为“从一个对象发送到另一个对象的消息”,那么说“玩家向工作人员发送'cut wood'消息更有意义”,而工作人员又发送'cut'消息给树“。
答案 7 :(得分:1)
对象设计就是为您的类分配职责。这意味着这个问题确实没有好的答案。因为这完全取决于你如何在 设计中建立责任。 (见:Larman)
因此你需要决定什么对象/类负责什么。这将引导您正确回答有关放置何种方法的问题。
因此问你自己的问题是:工人自己决定砍木头吗?如果他这样做,他可能不需要这样订购,因此他不需要方法 cut(tree)。但是如果用户可以命令他这样做,他将需要一个剪切(树)方法。另一个例子:树必须知道他被切断了吗?好吧,如果一棵砍伐的树只是导致他从福雷斯特移除,他可能不需要这样的 tree.cut()方法。但是如果你赋予树在切割过程中(重新)绘制自己的责任,你可能需要一个 tree.cut()方法。树甚至可以被建模为具有宽度,并且他可以计算在崩溃之前需要多少切割。
答案 8 :(得分:0)
由于单个工作人员可能会裁减多个树,因此您更有可能希望将cutWood()
放入工人类中。
答案 9 :(得分:0)
cut()
方法不在Saw
对象上吗?
更严重的是,我认为方法调用的目标是“主题”,方法本身是“动词”,其参数(如果动词是可传递的)是“直接对象”。因此,在此示例中,它将是worker.cut(tree)
。
答案 10 :(得分:0)
如果您解释cutWood
的内容,这个问题才能真正得到解答。
如果cutWood
仅影响Tree
的状态,则它属于Tree
,例如
public void cutWood() {
this.height = 0;
}
在calculateArea
的情况下,您只需要圆的半径(假设pi是常数)来进行此计算 - 没有别的。这就是它属于Circle
的原因。
停止尝试过于密切地模拟现实世界,看看你的方法实际需要做什么。
答案 11 :(得分:0)
这是一个有趣的话题。我有时会想到同样的情景。我认为一个好的方法,就是把方法放到具有最高凝聚力的课堂上。因此Tree类将是第一选择。另一方面,如果你试图匹配一个真实的世界模型,我会说工人类必须能够执行某些动作,包括切割树。我经常发现自己处于这种情况,并想知道在哪里放置这种方法的正确位置。另一种方法是一个知道工人和树的类,因此处理切割树的机制。这样两个类(树,工人)都不会对它有任何了解。