Factory Design Pattern
Overview
Factory design pattern is a creational design pattern that separates the logic of creating objects from the client code. The factory class in the factory design pattern is responsible for creating objects based on the request from the client.
When will We Need the Factory Design Pattern?
Imagine that you own a grab-and-go milkshake bar. Customers come to your restaurant and order milkshakes by paying money to the cashier. The cashier passes the order to the kitchen, where the milkshakes are prepared. The customers and cashier are decoupled from the kitchen, and the kitchen prepares the milkshakes. We have a shake factory (kitchen) which takes in orders, prepares and gives us the milkshakes.
Factory design pattern delegates the responsibility of creating objects to a factory class. Factory class has a factory method responsible for creating the requested object. This design pattern is also known as Simple Factory Pattern.
How does Factory Design Pattern Work?
We will understand the working of factory design patterns with the Milkshake Factory example mentioned above. We will create the Milkshake interface and concrete milkshake classes such as OreoMilkshake, ButterscotchMilkshake, and VannilaMilkshake. We will then create the MilkshakeFactory class with a factory method that accepts the type of Milkshake we want and returns the respective milkshake object.
Structure
Factory, Product, Concrete Products, Client are the core components of the factory design pattern.
Product
Product is an interface that will be produced by the factory class. For example, Milkshake will be produced by the milkshake factory.
Concrete Products
Concrete products are the various implementations of the Product interface. E.g., OreoMilkshake, ButterscotchMilkshake, and VannilaMilkshake.
Factory
A factory class is responsible for producing the products. It contains a factory method that creates concrete product objects. For example, MilkshakeFactory creates different milkshakes like OreoMilkshake, VannilaMilkshake, etc.
Client
The client is responsible for instantiating the factory class and creating Product objects using its factory method. For example, the client can get a milkshake instance by calling the factory class' prepare() method.
Implementation
- Create the Milkshake interface with the necessary attributes and methods.
- Create the concrete product classes ButterscotchMilkshake, OreoMilkshake, and VannilaMilkshake that implements the Milkshake interface.
- Create the MilkshakeName enumeration that holds the names of all the available milkshakes.
- Create the MilkshakeFactory class with the factory method prepare() that accepts a MilkshakeName as the argument.
- Create the Client class responsible for instantiating the MilkshakeFactory and calling its prepare() method with the required MilkshakeName.
Pseudocode
Milkshake
Let's start by creating the Milkshake interface. We don't add any attributes or methods to the Milkshake interface for simplicity. This is the product that will be produced by the factory class.
Pseudocode:
Milkshake Names
We create the enumeration MilkshakeName that contains all the available milkshakes. This name will be passed to the factory method to get the concrete milkshake objects.
Pseudocode:
Concrete Milkshakes
We create the concrete milkshake classes OreoMilkshake, ButterscotchMilkshake, and VannilaMilkshake that implements the Milkshake interface. These concrete milkshake classes contain a single attribute name and a no-argument constructor.
Pseudocode:
Milkshake Factory
We create the MilkshakeFactory class with a single factory method, prepare(). The prepare() method accepts a MilkshakeName as an argument and returns the corresponding concrete milkshake object. We create the mapping between MilkshakeName and concrete milkshake classes that will be used to get concrete milkshake instance by MilkshakeName.
Pseudocode
Client
We create the Client class responsible for instantiating the MilkshakeFactory. We call the factory method prepare() with a MilkshakeName to get the corresponding concrete milkshake instance.
Pseudocode:
Output
Explanation: We instantiated a MilkshakeFactory instance inside the main() method and called its prepare() method with the MilkshakeName to prepare concrete milkshake instances OreoMilkshake, ButterscotchMilkshake, and VannilaMilkshake.
Language Specific Code
Java
Milkshake
Milkshake Names
Concrete Milkshakes
Milkshake Factory
Client
Output
Python
Milkshake
Milkshake Names
Concrete Milkshakes
Milkshake Factory
Client
Output
C++
Milkshake
Milkshake Names
Concrete Milkshakes
Milkshake Factory
Client
Output
Pros and Cons of Factory Design Pattern
Pros
- Factory design pattern provides great extensibility that lets us add new classes without changing the application.
- Factory design pattern leverages loose coupling and eliminates hard binding the application-specific login in the code.
- The factory method returns the Product interface. So, it can work for any concrete product implementation.
Cons
- Creation of all the concrete product instances are tightly coupled with the factory class that involves code modification when a new concrete product is introduced.
Difference between Factory Pattern and Factory Method Pattern
Factory Design Pattern | Factory Method Desing Pattern |
---|---|
Factory design pattern contains a single factory class that is responsible for creating the concrete product instances | Factory method design pattern contains an abstract factory and several factory sub-classes responsible for creating the respective concrete products |
Example: PhoneFactory creates all phone types such as AndroidPhone, IPhone, etc. | Example: PhoneFactory is abstract, and there will be concrete factories such as AndroidPhoneFactory and IPhoneFactory to create AndoridPhone and IPhone |
FAQs
Q: What is a Factory in Factory design pattern?
A: The factory is a terminology that denotes a class or method responsible for creating/producing an object. E.g.: PhoneFactory is responsible for producing phones.
Q: What is a Factory method in Factory design pattern?
A: The factory method is responsible for creating and returning the objects to the client. A factory method may accept an input that denotes the type of object that needs to be created.
In this example, makePhone() is the factory method that produces phones based on the phoneType argument it receives.