2010-01-23 21 views
5

Digamos que tiene una clase llamada Explosion en la que no tiene sentido crear una instancia de la misma, sin cierta información de otra instancia de clase. El constructor no se hace público.Crear un objeto basado en el estado de otro objeto en Java

¿Es mejor hacerlo de esta manera:

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

O es mejor para la explosión de tener un método estático para la creación de una instancia y se pasa en un objeto de colisión como un argumento:

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

Cuando eres el autor de ambas clases.

+0

Terminé con las soluciones que más me gustan cuando diseño para pruebas de unidades sencillas. Los métodos estáticos y los "nuevos" operadores señalan clases específicas y dificultan las implementaciones simuladas. – Christian

Respuesta

1

Prefiero el segundo porque es OO.

4

¿Por qué el constructor no es público? Me parece sensato para Explosion tener un constructor que tome una referencia de colisión como parámetro.

De esa manera usted podría tener:

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

prefiero el segundo enfoque, ya que mejor divide la responsabilidad entre las clases. Para responder a su pregunta pregúntese quién tiene la responsabilidad de crear una Explosión y actúe en consecuencia. Su segundo enfoque básicamente utiliza un método de fábrica para ocultar el constructor, pero la responsabilidad sigue dentro de la clase Explosion, que es buena IMO.

¿Por qué el constructor no es público? ¿Puedes hacer que el paquete sea visible y luego pasar el Collision como un parámetro constructor?

3

Depende principalmente de la dependencia.

Si considera Explosion siempre un nivel inferior o un par de Collision, vaya por la flexibilidad y facilidad de uso de un método de instancia (virtual). Esto mantiene el comportamiento en los objetos y reduce la necesidad de getters (que tienden a ser un signo de diseño deficiente). Todavía tiene una llamada al constructor Explosion, solo que ahora está dentro de Collision.

Si, por otro lado, Collision no debe depender de Explosion, vaya directamente a un constructor. Este no es el final de los métodos virtuales. Si las cosas se vuelven más complicadas, puede cambiar el código de llamada para llamar a un método virtual en algún otro objeto que cree una configuración específica de Explosion desde una contraseña aprobada en Collision.

1

Realmente depende del alcance de su sistema. Si realmente quiere ir "al máximo", esto debería ser manejado por una tercera clase, que representa "física" en la interacción en su sistema.

He aquí por qué: En primer lugar, una colisión puede tener muchas consecuencias: explosiones, daños, puntuación (¿es este un juego)? sonido, etc. No desea sobrecargarlos a todos en la colisión.

Por otro lado, las explosiones pueden ocurrir por muchas razones diferentes (por ejemplo, armas), ¿debe la explosión conocer explícitamente todo lo que puede causarla?

Si está modelando muchas facetas del "mundo", es posible que desee tener un tercer sistema que sea responsable de estas causas y efectos.Toma lo que necesita del estado de un objeto, y crea el otro con el estado necesario sin que tengan que conocerse el uno al otro.

1
  • Effective Java (2nd chapter) recomienda el uso de un método de fábrica estática, es decir, su segunda opción.
  • en función de los parámetros de Collision que necesita en explosión, que puede ser mejor para pasar sólo los parámetros, por lo tanto no violar la Law of Demeter
1

Una ventaja con el segundo enfoque es que no es necesario crear objetos de explosión cada vez (refiriéndose desde Effective Java). Si desea tener algún tipo de mecanismo de almacenamiento en caché (digamos que desea devolver una misma instancia de Explosion en función de algunos atributos de clase Collision), entonces el segundo enfoque es útil.

Por otro lado, si la clase Explosion solo proporciona un método de fábrica estático para la creación de instancias, entonces no se puede subclasificar.

Cuestiones relacionadas