Home > Software design >  Store classes in a map and create objects after looking up the class
Store classes in a map and create objects after looking up the class

Time:10-15

I have three similar classes, and I want to instantiate one using a variable. Basically converting this:

Cell cell;

switch("CellA") {
  case "cellA":
    cell = new CellA(); break;
  case "cellB":
    cell = new CellB(); break;
  case "cellC":
    cell = new CellC(); break;
}

To something like this

Cell cell;

//Using a map
Map<String, Type> map = new HashMap<String, Type>();
map.put("cellA", CellA);  
map.put("cellB", CellB);
map.put("cellC", CellC);  //CellA, CellB, CellC are the class types

Type cellType = map.get("cellA");
cell = new cellType.getClass();   //This is problematic, I hope cellType is an alias to a cell class, so I can use keyword "new"

(Note: CellA, CellB, CellC extend Cell class)

I know this sounds a bit weird to do, but my professor really wants us to avoid switch statement. (It's a software design class)

CodePudding user response:

If you're using Java 8 you can implement a dynamic factory using suppliers:

public class DynamicFactory {

  private static final Map<String, Supplier<? extends Cell>> registry = new HashMap<>();

  public void register(String type, Supplier<? extends Cell> supplier) {
    registry.putIfAbsent(type, supplier);
  }

  public Cell getCell(String type) {
    return Optional.ofNullable(registry.get(type))
        .map(Supplier::get)
        .orElse(null);
  }

  public static void main(String[] args) {
    DynamicFactory app = new DynamicFactory();
    app.register("cellA", CellA::new);
    app.register("cellB", CellB::new);
    app.register("cellC", CellC::new);

    System.out.println(app.getCell("cellA"));  // CellA@8bcc55f
    System.out.println(app.getCell("cellB"));  // CellB@14dad5dc
    System.out.println(app.getCell("cellC"));  // CellC@764c12b6
    System.out.println(app.getCell("cellD"));  // null
  }

}
  • Related