Whenever you hide an implementation class behind an interface, you have the problem of instantiating the concrete instances of the interface and giving them to the client code.
There are several ways to do this:
- The client code can instatiate the instance directly
- The instance can be stored in a global resource such as a singleton or registry
- The code that instantiates the client can also create the instance and pass it to the client
- An instance can be created from a global property using reflection
Each of these techniques has disadvantages:
- If the client creates the instance then you can't substitute a different implementation without changing the client, and the benefit of using the interface is reduced.
- Using a global registry, singleton or property makes the client depend on the global facility which makes testing and reuse more difficult.
- Reflection is complicated when the instance had dependencies of its own, for example it needs configuration data or depends on other interfaces.
A solution to this problem that is gaining popularity is to use a framework with support for Inversion of Control (or, as Martin Fowler calls it, Dependency Injection). With this technique, client code can be written with no dependencies on global resources. The framework takes care of initializing the required instances and providing them on demand.
Martin Fowler has an article that explains the technique. Two frameworks that use this technique are Spring and PicoContainer.
|