Factory Pattern
Classic GOF Constructional Design Patterns
Intent
The classic Factory pattern is one of the most used design patterns in any object oriented language. The Factory pattern falls under creational patterns as this pattern provides one of the best ways to create an object. In the Factory pattern, we create objects without exposing the creation logic to the client and refer to newly created object using a common interface.
It is used when:
- Defining an interface for creating an object; but, we desire that sub-classes decide which exact class to instantiate. Essentially, this pattern lets a class defer instantiation to sub-classes.
- Defining a virtual constructor.
- Using a new operator is considered harmful or a bad practice.
Problem
We need to simplify and standardize a model for a range of applications, but allow for individual applications to define their own domain specific objects and provide for their creation.
Discussion
A Factory Method creates new objects as instructed by the client. One way to create objects is by invoking a constructor function with the new operator. There are situations however, where the client does not, or should not, know which one of several candidate objects to instantiate. The Factory Method allows the client to delegate object creation while still retaining control over which type to instantiate.
The key objective of the Factory Method is extensibility. Factory Methods are frequently used in applications that manage, maintain, or manipulate collections of objects that are different but at the same time have many characteristics (i.e. methods and properties) in common. An example would be a collection of documents with a mix of Xml documents, Pdf documents, and Rtf documents.
There is a great deal of confusion about how the Factory Method and the Abstract Factory patterns differ. One of the challenges is that in the original Gang of Four book, the two basically overlap. Essentially, the primary difference is where and how the creation takes place. With the Factory Method pattern, all that is required is a new operation. This simplicity makes the code much more customizable and adaptable as needs change over time and adds very little complexity (as commonly used today).
Structure
For the sake of this series, I will be focusing on the more current approach of how the Factory Method design pattern is implemented. In many cases today, the following definition is commonly substituted for the traditional definition or INTENT above. A method whose sole responsibility is to abstract the creation process of an object and return that object.. You may notices that this is a very narrow, special case of the classic Intent of the pattern. Given this definition, the simplest way to implement this pattern is via a static method,
As you can see in the diagram above, the client is totally decoupled from the implementation details of derived classes. Polymorphic creation is now possible.
Practical Example
The Factory Method defines an interface for creating objects, but lets sub-classes decide which classes to instantiate. This pattern can be applied many situations where you will need to create something specific that matches an interface. For example, it could be used to create shapes (circles, squares, triangles), dogs (german shepards, huskies, chihuahuas), or types of money (dollars, euros, yen). The traditional example is usually shapes, so, in the interest of being different, lets focus on a Factory Method example that concentrates on something near and dear - currency.
Much like the generic diagram in STRUCTURE above, anything that creates currency could return any of the defined type instances (yen, euros, or US dollars).
Let's extend this sample with some practical code below.
Code Samples
Below, you will find examples of the Factory Method implemented in four different commonly used languages. Each one of the examples implements the exact same scenario as described in the PRACTICAL EXAMPLE section above.
Each sample will use a factory method to return a specific currency instance.
C# Factory Method Code Sample for Currency
In this C# example, the CurrencyFactory creates three different types of currency. Each currency type has a different conversion rate, name, and country of origin. The createCurrency method is the actual Factory Method. The client instructs the factory what type of currency to create by passing a type argument into the Factory Method.
The AbstractCurrency in the diagram is implemented via an interface (ICurrency in this case) because C# does support interfaces. Because, we still need to ensure that all currency types have the same interface (properties and methods) we do this via implementing the interface on all child classes.
Three different currency types are created. Each currency type is asked to describe what they are along with their conversion rate and company of origin.
Java Factory Method Code Sample for Currency
In this Java example, the CurrencyFactory creates three different types of currency. Each currency type has a different conversion rate, name, and country of origin. The createCurrency method is the actual Factory Method. The client instructs the factory what type of currency to create by passing a type argument into the Factory Method.
The AbstractCurrency in the diagram is implemented via an interface (ICurrency in this case) because Java does support interfaces. Because, we still need to ensure that all currency types have the same interface (properties and methods) we do this via implementing the interface on all child classes.
Three different currency types are created. Each currency type is asked to describe what they are along with their conversion rate and company of origin.
Typescript Factory Method Code Sample for Currency
In this TypeScript example, the Factory interface creates three different types of currency. Each currency type has a different conversion rate, name, and country of origin. The createCurrency method is the actual Factory Method. The client instructs the factory what type of currency to create by passing a type argument into the Factory Method.
The AbstractCurrency in the diagram is implemented via an interface (ICurrency in this case) because Typescript does support interfaces. Because, we still need to ensure that all currency types have the same interface (properties and methods) we do this via implementing the interface on all child classes.
Three different currency types are created; all are stored in the same array. Each currency type is asked to describe what they are along with their conversion rate and company of origin.
The log function is just a helper which collects and displays results.
JavaScript Factory Method Code Sample for Currency
In this JavaScript example, the Factory object creates three different types of currency. Each currency type has a different comparison rate, nme, and country of origin. The createCurrency method is the actual Factory Method. The client instructs the factory what type of currency to create by passing a type argument into the Factory Method.
The AbstractCurrency in the diagram is not implemented because Javascript does not support abstract classes or interfaces. However, we still need to ensure that all currency types have the same interface (properties and methods). This is, of course, in no way guaranteed or enforced in Javascript.
Three different currency types are created; all are stored in the same array. Each currency type is asked to describe what they are along with their conversion rate and company of origin.
The log function is just a helper which collects and displays results.
Considerations
- If you have an inheritance hierarchy that exercises polymorphism, consider adding a polymorphic creation capability by defining a static factory method in the base class.
- Design the arguments to the factory method. What qualities or characteristics are necessary and sufficient to identify the correct derived class to instantiate?
- Consider designing an internal "object pool" that will allow objects to be reused instead of created from scratch.
- Consider making all constructors private or protected.
Additional Notes
- Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype.
- Factory Methods are usually called within Template Methods.
- Factory Method: creation through inheritance. Prototype: creation through delegation.
- Often, designs start out using Factory Method (less complicated, more customizable, sub-classes proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
- Prototype doesn't require sub-classing, but it does require an Initialize operation. Factory Method requires sub-classing, but doesn't require Initialize.
- The advantage of a Factory Method is that it can return the same instance multiple times, or can return a sub-class rather than an object of that exact type.
- Some Factory Method advocates recommend that as a matter of language design (or failing that, as a matter of style) absolutely all constructors should be private or protected. It's no one else's business whether a class manufactures a new object or recycles an old one.
- The new operator considered harmful. There is a difference between requesting an object and creating one. The new operator always creates an object, and fails to encapsulate object creation. A Factory Method enforces that encapsulation, and allows an object to be requested without inextricable coupling to the act of creation.