There is a little bit of confusion around this pattern because Factory Method can be implemented in many different ways but I want to stick with the original definition of the pattern.
The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
This pattern can be used by frameworks to delegate the creation of a specific concrete class at the extern of it in order to provide higher flexibility for their clients. The framework will provide logic using abstract classes or interfaces delegating to clients the responsibility to provide concrete implementations.
Suppose we want to create a very simple framework for a video library that provides a basic system to buy movies. However, because the policies about prices and permissions varies, the framework leave the clients the responsibility to create the specific policies.
Therefore, the framework defines an abstract class VideoLibrary that implements the buy operation:
As you can see, this class is abstract and the method GetPolicy is a Factory Method. It is responsibility of the client to create a subclass of VideoLibrary and return the appropriate policy. The framework simply define the IPolicy interface and the Customer and Book classes.
Let’s write a client that use our video library framework defining the following policies:
- Children can’t buy porn and horror movies
- Children always have a 50% discount
- Adults can buy any movies
- Adults pay the full price
- A child is a person with age lower then 18
This is the code:
This is an example of usage:
with the relative output:
This patterns provides a way to decouple the implementation of a class (IPolicy) from its use (in VideoLibrary). This is the flexibility that this pattern offers to clients.
The Object Oriented Design principle to keep in mind in this case is the following:
Depend upon abstractions. Do not depend upon concrete classes.
This principle is often called Dependency Inversion Principle.
In our example, the video library framework defines the abstraction IPolicy and does not depends upon concrete implementations. It demands to clients this responsibility and this is accomplished using inheritance.
A different way to describe the principle is:
High-level components should not depend on low-level components; rather, they should both depend on abstractions.
In our example, the high-level component is the VideoLibrary class while the low-level components are the implementations of the IPolicy interface. The IPolicy interface is the abstraction that has been created in order to invert the dependency.