Search code examples
javafactory-pattern

Create instances using one generic factory method


I am trying to find a easy to extend way to create objects at runtime based on a static String class attribute, called NAME.

How can I improve this code, which uses a simple if construct?

public class FlowerFactory {

private final Garden g;

public FlowerFactory(Garden g) {
  this.g = g;
}

public Flower createFlower(final String name) {
    Flower result = null;

   if (Rose.NAME.equals(name)) {
       result = new Rose(g);
   } else if (Oleander.NAME.equals(name)) {
       result = new Oleander(g);
   } else if ... { ... } ...

   return result;
}

newInstance() can not be used on these classes, unless I remove the constructor argument. Should I build a map (Map) of all supported flower class references, and move the contructor argument to a property setter method, or are there other simple solutions?

Background information: my goal is to implement some kind of 'self-registering' of new Flower classes, by FlowerFactory.getInstance().register(this.NAME, this.class), which means that from the very good answers so far the introspection-based solutions would fit best.


Solution

  • You can use reflection despite having a constructor argument:

    Rose.class.getConstructor(Garden.class).newInstance(g);
    

    Combined with a static name to class mapping, this could be implemented like this:

    // TODO handle unknown name
    FLOWERS.get(name).getConstructor(Garden.class).newInstance(g);
    

    where flowers could be populated in a static initializer block:

    static {
      Map<String, Class<? extends Flower>> map = new HashMap<String, Class<? extends Flower>>();
      map.put(Rose.NAME, Rose.class);
      // add all flowers
      FLOWERS = Collections.unmodifieableMap(map);
    }