It all depends on how separate you want your Shape
s and Formation
s to be. The simplest solution would be--as you mentioned--to add a Formation createFormation()
method to the Shape
interface.
But if you're trying to keep Shape
s and Formation
s separate, you'll have to do something more advanced. I would recommend NOT using the visitor pattern, since it is very inflexible.
As an alternative, consider adding a FormationBuilder
class:
public interface FormationBuilder
{
/**
* Builds a particular Formation implementation from the given shape.
* Perhaps the shape is passed into the constructor of the Formation,
* perhaps this method extracts the necessary information to build the
* Formation...
*/
Formation build(Shape shape);
}
This can be used with a factory such as this:
public class FormationFactory
{
private final Map<Class<? extends Shape>, FormationBuilder> builders
= new HashMap<Class<? extends Shape>, FormationBuilder>();
public <T extends Shape> void register(
Class<T> shapeType, FormationBuilder builder);
{
builders.put(shapeType, builder);
}
public Formation getFormation(Shape shape)
{
return builders.get(shape.getClass()).build(shape);
}
}
But now the question is, where should the Factory
be initialized. Whether or not this fits your needs depends on how your code is structured.