基于Java中另一个对象的状态创建对象

时间:2010-01-23 15:48:30

标签: java

假设您有一个名为Explosion的类,在没有其他类实例的某些信息的情况下创建它的实例是没有意义的。构造函数未公开。

以这种方式做得更好:

// both classes are in the same package  
Explosion e;  
Collision c = new Collision()    
// do some stuff with collision  
e = c.createExplosion()

或者爆炸有一个静态方法来创建一个实例并将一个Collision对象作为参数传递它是否更好:

Explosion e  
Collision c = new Collision()    
// do some stuff with collision  
e = Explosion.createExplosion(c)

当你是这两个班的作者时。

7 个答案:

答案 0 :(得分:4)

为什么构造函数不公开?对于Explosion来说,拥有一个以碰撞引用作为参数的构造函数对我来说似乎是明智的。

你可以这样:

Explosion e;
Collision c = new Collision();
// do some stuff with collision
e = new Explosion(c);

答案 1 :(得分:3)

我更喜欢第二种方法,因为它更好地划分了类之间的责任。要回答您的问题,请问自己谁有责任创建爆炸,并采取相应的行动。你的第二种方法基本上使用工厂方法来隐藏构造函数,但是责任仍然在Explosion类中,这是一个很好的IMO。

为什么构造函数不公开?你可以让它包可见,然后只是将碰撞作为构造函数参数传递?

答案 2 :(得分:3)

这主要取决于依赖性。

如果您认为Explosion始终是Collision的较低级别或同级,那么请考虑(虚拟)实例方法的灵活性和易用性。这可以保持对象中的行为,并减少对getter的需求(这往往是设计不佳的标志)。您当然仍然可以调用Explosion构造函数,但现在它只在Collision内。

另一方面,如果Collision不应该依赖Explosion,那么直接去构造函数。这不是虚拟方法的结束。如果事情变得更复杂,您可能会更改调用代码以在其他对象上调用虚方法,该对象从传入的Explosion创建Collision的特定配置。

答案 3 :(得分:1)

我当然更喜欢第二种,因为那是OO。

答案 4 :(得分:1)

这实际上取决于系统的范围。 如果你真的想要“完全伸展”,这应该由第三类处理,代表你系统中交互的“物理”。

原因如下: 首先,碰撞会产生很多后果:爆炸,伤害,得分(这是游戏)吗?声音等。您不希望将所有这些重载到碰撞中。

另一方面,爆炸可能由于很多不同的原因(例如武器)发生,如果爆炸明确地知道可能导致它的一切吗?

如果您要为“世界”的许多方面建模,您可能希望拥有一个负责这些因果关系的第三个系统。它需要一个对象的状态所需要的东西,并在必要的状态下创建另一个对象而不必彼此了解。

答案 5 :(得分:1)

答案 6 :(得分:1)

第二种方法的优点是您不必每次都创建Explosion对象(参考Effective Java)。 如果你想拥有某种缓存机制(比如你想根据碰撞类的某些属性返回相同的Explosion实例),那么第二种方法是有用的。

另一方面,如果Explosion类仅为实例创建提供静态工厂方法,则它不能被子类化。