Reputation: 1553
Lets assume I have a database table like:
Table Building
ID int (primary key)
title varchar
And to fetch this, I have a Java Class like:
class Building{
private Integer ID;
private String title;
...
}
(Add some JPA annotations in your imagination if that helps you).
But now, depending on the actual Building, I want to execute some logic.
My first thought was to create a big switch/case like:
switch(building.getId()){
case 1:
BuildingA buildingLogic = new BuildingA(building);
break;
case 2:
BuildingB buildingLogic = new BuildingB(building);
break;
...
}
buildingLogic.doBuildingSpecificStuff();
But that would end in an endless switch/case, which would not be very clear to "read".
My next thougt (already covered by the answer of Mark Elliot) was to write the actual Class name into the database as an additional field (BuildingClass) and with some (to me currently unknown) java magic, create the object from the building.getBuildingclass()
String, but I already assume that would have some sort of disadvantages...
So I thought maybe you people could give me some more ideas or comments on my thoughts.
Upvotes: 1
Views: 327
Reputation: 77104
Supposing you did have the class name, you could use reflection to instantiate a new instance, though there are some security and performance risks for going down this path.
String className = "com.foo.bar.Baz";
// gets the actual class (might throw an Exception if the class doesn't exist)
Class<?> clazz = Class.forName(className);
// probably want to have some common interface these conform to, so
// let's assume you have one, you can test this is the right kind of class
CommonBuildingType buildingLogic = null;
if (CommonBuildingType.class.isAssignableFrom(clazz)) {
// get the constructor to invoke (might throw if no match)
Constructor constructor = clazz.getDeclaredConstructor(Building.class);
// safe to cast, we checked above
buildingLogic = (CommonBuildingType) constructor.newInstance(building);
} else {
// throw an exception?
}
Upvotes: 2