Factory Method is an extremely simple yet very useful design pattern. I'd rather call it a simple programming technique. A technique that might be second nature to most people designing OO these days but since it's part of Gamma's design patterns book, albeit a terse discussion, I'd rather talk about it here since I know it will come up in other discussions that I'm planning on posting down the road.
The factory method pattern is based on a simple concept: I'll call you when I need to create something. Unlike other patterns we have discussed where the client code will use the results of the pattern to do something, the factory method's client code is usually a class which extends the abstract class available in this pattern and the abstract class will call the client code whenever it needs a new object. For a simple definition please see here.
The best example (which you usually find in any discussion in regards to this pattern) is the Application framework example. For those who are familiar with MFC and have used it during their Visual C++ days or for those who had worked with Borland C++ (for Windows) this example is quite familiar. You are designing an application framework which will handle most generic application functionality. Stuff like bringing up the open dialog when the user chooses File – Open or taking care of 'Save As…', toolbars, status bar etc. But this application framework wouldn't be able to do anything useful since it's just a framework. The person responsible for the actual development of the concrete requirements would take the framework, probably inherit from it and fill in the blanks for example when the actual save happens (after the save dialog has been taken care of etc.) write the information needed to the file. Write the program logic and things like that.
This application framework can be reusable and developed independent of any specific requirement or domain due to the fact that it leaves the details out for the person doing the implementation based on the framework. One of the things that the framework needs is documents created whenever the framework needs them or in the case of the MFC framework Views were also another example. So we have some logic at the framework level that takes care of different things but this logic is unable to finish the job unless we (the class extending the framework) create the specific product that we need and hand it back to the application. This is one of the major uses of the factory method pattern. Let's take a look at all this discussion from a programming point of view:
When I'm developing the application framework I would write code like this:
abstract class Application
/* complex logic in relation to how the application will work
during this complex logic at some points I need the document
class so I call CreateDocument() and use whatever is returned
protected abstract Document CreateDocument();
abstract class Document
/* abstract and concrete methods implementing the Document class */
When a developer comes along and wants to use my framework to create an actual application and provide the logic for that application's specific requirements they would write this:
class MyApp : Application
/* logic related to this application’s specific requirements. Some of this
logic might be new methods and others will be overrides of the base
protected override Document CreateDocument()
return new MyDoc();
class MyDoc : Document
/* implementation related to this application’s requirements */
It's quite obvious from the above code that this pattern is relying on a very simple concept: polymorphism. But there are a couple of interesting things in regards to the way this is used:
Use of this pattern will provide a simple alternative to other creational patterns where you need to provide future users of a class (or framework) that you develop to decide what type of a product will be created and used.
It's very important to only use this pattern in scenarios where the inheritance is natural and due to other design decisions not specifically because of the use of this pattern. In other words if in the above example I had to create a subclass of the Application class only to override the CreateDocument method it would have been too much work and wouldn't have made any sense. But if I had to do the inheritance for other reasons (i.e. needed to override other methods and extend the general functionality provided by the base class) then using this pattern to create a flexible creation mechanism is a good choice.
In every single scenario that you can use this pattern you can also use the abstract factory pattern. Obviously it's not a good choice to use the abstract factory pattern in place of this pattern every time but it's good to know that this pattern doesn't really add anything to your patterns repository except for the fact that it's a simplification of the abstract factory pattern which you can use in special occasions. Let's examine this in more detail:
What happens with this pattern is that the client code from the abstract factory pattern and the abstract factory itself are squished together to form the Abstract Creator (the Application class in the above example) of the pattern. So in every example you can do the re-design using abstract factory with this pattern by simply separating these two pieces. Let's assume that we want to take the above example and re-design it using the abstract factory pattern. Here is what we get:
/* the logic related to app.
when ever this class needs a Document
it will call Creator.CreateDocument();
public DocumentAbstractFactory Creator = //initialized in some way that fits your problem
abstract class DocumentAbstractFactory
public abstract Document CreateDocument();
As you can see we re-configured the Application class to call an abstract factory that we have configured into the Application object (Creator). So the person extending this framework to create specific Documents (such as MyDoc) would need to create a concrete factory class that implements the CreateDocument method and somehow configure the Application object to use that specific Concrete Factory.
To wrap things up I should add that usually the requirements of the problem we are trying to solve will point us to either the Abstract Factory pattern or the Factory Method pattern so we should be careful to analyze the requirements in detail but it's comforting to know how close these two patterns are. Just to help you decide here are my criteria for deciding between these two patterns:
- Use the factory method pattern when you want to allow future programmers to extend a class and provide different products for the class's use. The sub-classes created should be because of other decisions and not the use of this pattern.
- In scenarios where multiple products exist or multiple product families exist and there is going to be switching between the different families based on specific criteria the use of abstract factory is usually much more helpful.
- If you want to map two parallel hierarchies of inheritance to one another the factory method pattern will help a lot. I will discuss this in future posts.
- If you get stuck and can't decide use the abstract factory pattern. You might have to write a little bit more code but you have a whole lot more flexibility.