Too many factories as a result of writing testable code
I'm trying to write code that can be easily tested. That leads me to avoiding calling new Class1() directly. Instead I usually create an interface, a simple factory with one GetObject() method that returns this interface.
It works fine. The problem I find is too many factories that basically od nothing except calling new Class1() (or whatever class/interface they are responsible for creating). I don't think it's a big price to pay for having testable code but still... Does anyone use a better aproach and still achieve the goal of being able to inject a different implement开发者_高级运维etaion of Class1 at test time?
I know I could expose the Class1 implementation as property and use a default value at runtime but that would mean I'm limited to one instance while in many cases I want to create a new instance each time I need that Class1.
Edit:
I do use IoC and that indeed helps. Nevertheless, I usually end up having a factory as a dependency in the IoC configuration. My GetObject methods usually call something like IoC.Resolve. I prefer to have the IoC dependency isolated in the factories and not directly in the domain classes that contain business logic.There are many frameworks that help in achieving this. The technique is called inversion of control. Examples in the .NET world:
- Spring.NET
- StructureMap
- Castle Windsor
The common point of all these frameworks is the ability to externalize bindings between components (classes) into a configuration, which is either expressed as a configuration file (i.e. in XML) or a 'bootstrap' code. They are able to inject dependencies automatically into instances and overtake the problem of class instantiation and configuration for you. Basically, you can leave this task upon the IoC container and quit creating custom factory classes.
The relevant resources on SO are tagged ioc-container.
Martin Fowler has an article describing IoC and implementation techniques like dependency injection and service locator.
It would be easier if I knew what language you are talking about, but most languages have some concept of generics or other. So you can make your factory interface a generic one:
Java version:
public interface Factory<K>{
K create();
}
The Guava Libraries have the Supplier<K>
interface for exactly this purpose. I'd suggest using such a quasi-standard (I guess something similar will be available for other languages also).
精彩评论