Reputation: 14820
Since I don't have a java background I'm struggling to create a factory object that returns implementations of a specific interface. Something similar to this...
Factory.create();
where create
should return an interface. Obviously, create
needs to know what I'm trying to "create". It could be by passing in a enum
so that create
can switch through all values of the enum
and decide what to create/return...I don't know exactly what's the best way to go about this.
The main problem I'm trying to solve is to provide an implementation-agnostic solution where consumers of this "factory framework" don't need to know anything about the implementation details. This allows me to change implementation classes and even swap out concrete implementations without having to re-factor an entire application or system.
I have the following interface in place
public interface EntityValidator<T> {
public boolean isValid(T t);
public List<String> getErrors();
}
and so far a couple of implementations that look like the class below...
public class Foo implements EntityValidator<EntityA> {
private List<String> errors;
public boolean isValid(EntityA a){
///implementation details
}
public List<String> getErrors(){
return errors;
}
}
the actual example is a fair bit more complex since there's an abstract class involved but that's out of the scope of this question. And finally the factory object, which is where I'm stuck at the moment
public final class EntityValidatorFactory {
public static <T> EntityValidator<T> create(MyEnum value){
if(value == VALUE_X){
//THIS IS WHERE I'm stuck
}
}
}
I can't seem to find the way to return out of the if
statement (which could be a switch
BTW)
Is there a way to return a generic interface from a concrete class that implements it without having to manually cast it to that interface?
Any solution would be appreciated as long as it doesn't involve change the consuming code when I change or swap implementation classes.
Upvotes: 1
Views: 2762
Reputation: 11483
As with anything in programming, it's a question of input and output; what you need and what you have.
What you need is up to you, for starters, you obviously need a way to determine the type that you're instantiating, so we could start there:
public <T> T create(Class<T> type) {
//make T
}
From there, you need to decide the standard for instantiation, whether that's requiring a bound for T (Like T extends MyInterface
), or using reflection and having a pre-defined constructor / zero-args constructor. You could also have a Map<String, Object>
which contains the arguments to create the object; it's really up to you. The end point is that you just need to decide a way to make the object, and keep that standard consistent if you're going to make a "multi-type" factory.
For most things, however, you would just make the method for the specific object you need, instead of passing the types themselves (multiple Factory types). Factory, from experience, comes in two forms:
A class which hides the implementation details by choosing the correct subclass for you
A class which handles the instantiation and controls references to the object
So you really have a lot of flexibility here.
Upvotes: 0
Reputation: 338516
As seen in the Wikipedia article on the Factory pattern, to make differing concrete versions of the factory’s output objects, your factory itself should actually be various different factory classes. The various factory classes should be implementing a shared factory interface or extending a shared factory abstract superclass.
By the way, I've seen the verb make
used with Factory classes to stick with the metaphor of a real physical factory that makes things. You may want to use that word rather than "create".
Upvotes: 2