Question

In most of the cases when we write a factory method it is a bunch of if conditions which can keep on growing. What is the most effective way of writing such a method (with the least if conditions)?

public A createA(final String id) {
    if (id.equals("A1")) {
      return new A1();
    }
    else if (id.equals("A2")) {
      return new A2();
    }
    return null;
  }
Was it helpful?

Solution

You could use a Map<String, Supplier<A>>:

Map<String, Supplier<A>> map = new HashMap<>();
map.put("A1", () -> new A1());
map.put("A2", () -> new A2());

...

public A createA(final String id) {
    Supplier<A> supplier = map.get(id);
    if (supplier != null) {
        return supplier.get();
    }
    throw new IllegalArgumentException("unknown id: " + id);
}

This uses a standard Java 8 Supplier interface, with a Java 8 lambda syntax, but you could of course define your own Supplier interface, and create instances using anonymous inner classes.

OTHER TIPS

I like a archetype map approach - just fill the archetypes up at some stage - either in a static block or the class constructor. Code looks roughly like this

  Map<String, A> archetypes;

  public A createA(final String id)
  {
     A a = archetypes.get(id);
     return (a!=null)?a.copy():null;
  }

This method is lazy initialization. Assuming you have classes that correspond to the name in id:

public A createA(final String id) {
  // warning, should not use an id string that is tainted (eg from user input)
  return (A) Class.forName(id).newInstance();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top