2010-01-23 106 views
5

假设您有一个名为Explosion的类,在创建它的实例时没有意义,而没有来自另一个类实例的某些信息。构造函数不公开。根据Java中另一个对象的状态创建一个对象

是更好地做这种方式:

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

或者是爆炸最好有一个静态方法来创建一个实例,你在一个碰撞对象作为参数传递:

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

当你是这两个类的作者。

+0

当我为简单的单元测试进行设计时,我最终选择了最喜欢的解决方案。静态方法和'新'运算符指出特定的类并使模拟实现变得困难。 – Christian 2010-01-23 16:20:31

回答

1

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

4

为什么构造函数不公开? Explosion有一个构造函数,它将Collision引用作为参数对我来说似乎是明智的。

这样,你可以有:

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

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

为什么构造函数不公开?你可以使它包装可见,然后通过碰撞作为构造参数?

3

这主要取决于依赖性。

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

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

1

这真的取决于您的系统的范围。 如果你真的想要“完整的延伸”,这应该由第三类来处理,代表系统中的交互的“物理”。

这是为什么: 首先,碰撞会产生很多后果:爆炸,伤害,得分(这是一场比赛)?声音等等。你不想将它们全部放入碰撞中。另一方面,爆炸可能由于许多不同的原因而发生(例如武器),爆炸是否应该明确地知道可引起爆炸的所有因素?

如果你正在模拟“世界”的许多方面,你可能想要第三个系统负责这些因果关系。它需要它所需要的一个对象的状态,并创建另一个具有必要的状态而不必彼此了解的对象。

1
  • Effective Java (2nd chapter)建议使用静态工厂方法,即您的第二个选项。
  • 根据从Collision您在爆炸所需要的参数,它可能是更好的传递只有那些参数,因此不会违反与第二种方法的Law of Demeter
1

一个优点是你不需要创建防爆对象每次(参考Effective Java)。 如果你想拥有某种缓存机制(比如说你想基于类Collision的某些属性返回一个相同的爆炸实例),那么第二种方法是有帮助的。

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

相关问题