2011-09-01 78 views
7

我想写一个简单的球类比赛,并且有几个转身(即球的生命)。当球通过屏幕底部边界时,球“死亡”。我至今的作品,但并不似乎是做事情的正确方法:对象是否可以自行移除?怎么样?

if (ball.getY() > bottomOfScreen) { 
    ball.die(); 
    remove(ball); 
} 

模具()方法基本上淡出球的颜色慢慢地(dark_gray - >暂停(50) - > light_gray - >暂停(50)),但实际上并没有做任何有用的事情。

显然,remove()从屏幕上摆脱了球,这正是我想要的。对我来说这个remove()是Ball的die()方法的一部分,而不是它在主程序中是一个单独的方法调用 - 但我不知道如何去做这件事?

对象是否可以自行删除?而且,如果可以的话,从哲学/方法论角度来看,反对比谋杀更好吗?

谢谢!

+0

只有一个建议。删除应首先确保球死亡,如果没有,然后调用它的方法die(),然后将其删除。 –

回答

4

由于对象具有对视图渲染机制的某种引用,因此该对象可以将其自身删除。您的样品不提供足够的信息,所以我会举例说明这样做的一种方法:

public class Ball { 
    private ViewRenderer view; 

    public void remove() { 
     view.remove(this); 
    } 
} 

也不自杀也不谋杀是好还是坏。这取决于你的设计和要求。

在这个例子虽然谋杀可能是因为这样的Ball对象需要知道在哪个上下文的正在使用最好

+1

对不起,我必须为此付出代价。它可以工作,但它引入了一个循环引用 - Ball引用了ViewRenderer,并且(大概)ViewRenderer引用了Ball。这样的事情会使测试比他们需要的复杂得多。 – DJClayworth

+0

感谢您解释您的推理。你是对的,尽管在更复杂的情况下(即使用MVC/Observer模式),对象可能会请求删除,例如通过常规变更处理程序。 –

2

从某种意义上说,从内存中删除对象:不,在垃圾回收器专门处理的Java中。

你可以做的是从包含它的集合中删除对象,但是这会要求对象有权访问这些集合(在大多数情况下这是不可行的,因为可能有很多集合)。

我会建议包含对象(在你的情况下屏幕)轮询包含的对象的(球)的状态,并删除它后,它实际上已经死了。

3

可以创建一个方法,在该方法中球可以自行移除,但这是一件坏事。为了从屏幕上移除它,球必须有一个对屏幕的引用。这会创建一个循环的引用链(Ball有一个对屏幕的引用,屏幕引用了Ball),这会使您的设计更加复杂,并且您的测试更加复杂。

自杀很好 - 屏幕告诉球死了,球死了。但这是关于消除关系,而不是死亡。维持这种关系的东西是屏幕,所以它应该是做删除的事情。

另外请记住,两者不一定必须一起发生。屏幕可能因为某种原因想要保持死球,并且它可能想要移除一个没有死的球。即使现在您的应用中没有发生这种情况,也要考虑到这种可能性。

1

大概有一些物体(例如,屏幕或Johan的示例中的ViewRenderer),该对象持有对Ball的引用,并且删除该引用必须由屏幕(“对象谋杀”)完成。 “对象自杀”等同于Ball将消息传递给屏幕,要求“被谋杀”。

因为Ball知道它何时通过了边界,所以对我来说(对于你的设计的细节不知道你的设计的细节)对于由Ball发起的去除是有意义的。然后屏幕可以通过以下几种方式中的一种查找有关此更改的信息:

  • 屏幕可以轮询球。
  • Ball可以持有对Screen的直接反向引用,这会创建一个不幸的循环依赖。
  • 球可以通过一个BallObserver接口保存对屏幕的引用。这是observer pattern的应用程序。

第一个是最简单的,如果它自然地适合您的绘制屏幕的机制,这将是一个不错的选择。第三种原则上更灵活,但在实践中你可能不需要这种灵活性。在一个简单的程序中,中间选项可能没问题,但你可以把它看作是迈向第三步的一步。

如果你有一个屏幕(或ViewRenderer,或其他)的对象,真正的意思是“在主程序中的一个单独的方法调用”,那么你应该重新考虑你的设计。

0

不,对象不能自杀。任何参考本身只是一个参考。

要“清除”其内部的对象,只需清除所有实例变量。

要“清除”自身以外的对象,可以将变量设置为null。

相关问题