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
}
}