I have an Enum like this:
public static enum TestEnum {
// main
ENUM_A (1, "test1", TestADto.class),
ENUM_B (2, "test2", TestBDto.class),
ENUM_C (3, "test3", TestCDto.class),
...
private Class<? extends Dto> dtoClass;
public Class<? extends Dto getDtoClass() {
return dtoClass;
}
...
}
All of these dto classes extend the same abstract (dto) class:
public abstract class AbstractDto {
private String foo;
private int bar;
...
AbstractDto(AbstractClassNeededForInitialization o) {
this.foo = o.getFoo();
this.bar = o.getBar();
}
... some functions here ...
}
This would a example Dto implementation of TestADto:
@Getter
@Setter
public class TestADto extends AbstractDto {
private String anotherFoo;
private int anotherBar;
...
public TestADto(AbstractClassNeededForInitialization o) {
super(o);
}
... some functions here ...
}
Is it possible (im using Java 8) create a concrete instance of these in the enum reference classes without the need of knowing which concrete istance it is?
Lets say im at a certain point in a function and im having the Enum_A. Now i want to create a dto instance (TestADto.class). What would be the best approach or pattern for this?
Imagine a enum with more than 100 entries and every entry has a different dto which extends the same abstract dto or implements a interface.
How can i create these concrete object without writing a huge if else or switch statement or handle it case by case.
I read something about reflection and proxies but not sure if this is the right way i am. Or is the current state im having already a kind of poor design? Everything i want to reach is to assign the dto name to an enum for creating it later at some certain points. But without creating a huge condition if possible...
@Edit
I forgot to mention that creating a instance of each dto needs to have object which is passed to the constructor. This object which is passed to the constructor also implements a interface.
If you need to invoke an empty constructor for your DTO subclasses, you could provide a Supplier
in the enum constructor that you store in a field :
...
ENUM_A (1, "test1", TestADto::new),
ENUM_B (2, "test2", TestBDto::new),
ENUM_C (3, "test3", TestCDto::new);
private Supplier<Dto> supplierDto;
TestEnum(int i, String name, Supplier<Dto> supplierDTO){
this.supplierDto = supplierDTO;
...
}
...
Then you can create the Dto instance by invoking supplierDto.get();
After your edit :
I forgot to mention that creating a instance of each dto needs to have object which is passed to the constructor.
A Supplier<Dto>
doesn't suit any longer as it is not designed to be used with a constructor that presents one parameter.
By Supposing that your constructors are like that :
public class TestADto{
...
private MyInterface myInterface;
public TestADto (MyInterface myInterface){
this.myInterface = myInterface;
}
...
}
You could so declare in the enum constructor a Function <MyInterface, Dto>
parameter to match to this constructor.
...
ENUM_A (1, "test1", TestADto::new),
ENUM_B (2, "test2", TestBDto::new),
ENUM_C (3, "test3", TestCDto::new);
private Function <MyInterface, Dto> dtoConstructor;
TestEnum(int i, String name, Function <MyInterface, Dto> dtoConstructor){
this.dtoConstructor = dtoConstructor;
...
}
public Dto createInstance(MyInterface myInterface){
return myInterfaceToDtoFunction.apply(myInterface);
}
...