开发者

Creating an object based on the state of another object in Java

Lets say you have a class called Explosion where it does not make sense to create an instance of it, without some information from another class instance. The constructor is not made public.

Is it better to do it this way:

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

Or is it better for Explosion to have a static method for creating an instance and you pass in a Collision object as an argument:

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

When you are the开发者_运维百科 author of both classes.


Why is the constructor not public? It would seem sensible to me for Explosion to have a constructor that takes a Collision reference as a parameter.

That way you could have:

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


I prefer the second approach as it better divides the responsibility between the classes. To answer your question ask yourself who has the responsibility to create an Explosion, and act accordingly. Your second approach basically uses a factory method to hide the constructor, but the responsibility is still within the Explosion class, which is good IMO.

Why is the constructor not public? can you make it package visible and then just pass the Collision as a constructor parameter?


It depends... largely on dependency.

If you consider Explosion always a lower-level or a peer of Collision, then go for the flexibility and ease-of-use of a (virtual) instance method. This keeps behaviour in objects, and reduces the need for getters (which tend to be a sign of poor design). You still of course have a call to the Explosion constructor, only now it is within Collision.

If, on the other hand, Collision should not depend upon Explosion then go for a constructor directly. This is not the end of virtual methods. If things get more complicated you might change the calling code to call a virtual method on some other object that creates a specific configuration of Explosion from a passed in Collision.


I certainly prefer the second because that is OO.


It really depends on the scope of your system. If you really want to go "the full stretch", this should be handled by a third class, representing "physics" on interaction in your system.

Here is why: First, a collision can have a lot of consequences: explosions, damage, scoring (is this a game)? sound, etc. You don't want to overload all of them into the collision.

On the other hand, explosions can happen for a lot of different reasons (e.g., weapons), should the explosion explicitly know everything that can cause it?

If you are modeling a lot of facets of "the world", you may want to have a third system that is responsible for these cause-and-effects. It takes what it needs of the state of one object, and creates the other with the necessary state without them having to know about each other.


  • Effective Java (2nd chapter) recommends using a static factory method, i.e. your second option.
  • depending on the parameters from Collision that you need in explosion, it may be better to pass only those parameters, thus not violating the Law of Demeter


An advantage with the second approach is that you need not create Explosion object every time (referring from Effective Java). If you want to have some kind of caching mechanism (say you want to return a same instance of Explosion based on some attributes of class Collision) then the second approach is helpful.

On the flip side, if Explosion class only provides static factory method for instance creation then it cannot be subclassed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜