The problem / question.
I am trying to decouple as much as possible implementations and interfaces/abstract classes, in order to be able to switch implementations easily.
I learnt that the way to go was dependency injection, but before using a whole framework for that I would like to implement/understand the mechanism.
I also learnt that one way to implement dependency injection was to use abstract factories.
I am trying to use them in the following code, but I don't see where I get more decoupling between clients and implementations. I think I may not understand / implement the factory design pattern correctly to resolve this problem.
The sample situation
Let's say I have :
a mapper which is a generic interface :
public interface Mapper<A,B> { [mapper methods]}
a concrete class that implements this mapper interface:
JsonMapper implements Mapper<Json,ModelObject>{ [mapper methods implemented..] }
Now I want to use a mapper in a third object, a repository for instance :
OnlineRepo {
// reference to an interface (which is good I guess)
Mapper<Json, ModelObject> mMapper;
// constructor needs a concrete Mapper<Json, ModelObject>
OnlineRepo(Mapper<Json, ModelObject> jsonToModelMapper ){
mMapper = jsonToModelObject;
}
// other OnlineRepo methods using mMapper, get, upsert etc etc...
[...]
}
And finally my main code would have to instanciate the correct concrete classes. <- that's what I don't like.
main{
JsonMapper mapper = new JsonMapper(); // reference to concrete JsonMapper
OnlineRepo repo = new OnlineRepo(mapper); // inject concrete JsonMapper
}
How would the factory design pattern help me decouple these objects ?
The
OnlineRepository
does not directly reference the concreteJsonMapper
it references only the abstractMapper<Json, ModelObject>
. Isn't it ?How would an abstract factory design pattern help me decouple this code even more.
It seems like I will always need to reference an implementation in my main program (if not an implementation of JsonMapper, an implementation of JsonMapperFactory ?).
To better illustrate I do not see the advantage of this :
over this :
What I would like to be able to do :
I would love to be able to do that in main (my client) :
Mapper<Json, ModelObject> = GenericMapperFactory.getMapper()
And that would deliver a JsonMapper automatically.
I could also do things like
Mapper<xml, ModelObject> = GenericMapperFactory.getMapper()
and get the correct concrete object.
disclaimer
I hope my question is clear, if not, do not hesitate to tell me so I can work on it. These concepts are not yet completly clear for me so I have trouble writing clear an consise questions.
Thanks in advance for your help. Best, Antonin