Okay, we’re onto the first of what I described as the “stone cold brilliant patterns”. This particular one looks obvious, but its benefits are actually quite subtle. There are basically only two ways of creating an object in .NET:
- Call new
- Call a function that calls new
The factory pattern is basically just using the latter. Now, this might strike you as an unnecessary level of indirection, and you might be right. You’d be right if:
- The class is a pure data transfer object.
- The class doesn’t have a complex data structure.
- The class has no functional logic.
I’d rather not talk about testing too much, but what this comes down to is “The object could be easily created in a test.” Now, if you’re not that into testing (because, I don’t know, maybe you like bugs…) you might be wondering why I’m going on about testing. Well, testing is re-use. These objects are what I term “Leaf Objects”. They’re the basic values in our system. Everything else, you need a factory.
The whole point of the pattern is to avoid the basic drawback of new: that it isn’t polymorphic. You can’t call new Employee() and receive a MicrosoftEmployee object. And even if you don’t want that to happen, one day you probably will wish you could.
Incidentally, don’t create a static factory method. If you do, you’ve missed the whole point. The same goes for putting significant logic into your factory. Logic mixed with object creation is inflexible. In C++, you can overload the behaviour of the new operator. This, sadly, isn’t as useful as it first appears, since again it’s a static operation and cannot be varied according to runtime context. There’s no way to achieve the design benefits of the factory pattern.
The Difference between Factory and Abstract Factory
To be honest, I don’t really think the distinction between factory and abstract factory is useful:
- Factory Method. You declare a variable of type Func<>. There’s not much more to it, really.
- Abstract Factory: You declare an interface in which every method returns or creates an object
It’s the difference between one function and multiple functions.
I don’t honestly think I’ve done this pattern justice. It’s probably the single most important design pattern we’ve got. It falls into an interesting category: one where it’s obvious what you do, but much less obvious when you should use it. It took me years to appreciate how important it was to well-designed code. I started to understand it through reading Miško Hevery‘s work and applying that to my own experience of where my own testing approach was falling down.