Understanding Factory Pattern
This is the fourth article of the design pattern article series. If you haven’t read previous articles yet, I suggest you read that before proceeding with this article.
Article series:- Design Patterns with Java
Factory pattern is also known as Factory method pattern and it is falling under the creational design pattern. The main objective of the Factory pattern is to create instances without exposing the instantiation logic to the client. Actually, this is one of the most used design patterns in Enterprise applications. The ResourceBundle, NumberFormat classes are some examples of the Factory pattern in Java.
You can see there are many methods of NumberFormat class to get an instance. But you cannot find the implementation of these classes. That’s how the factory method works.
Let’s see a common UML diagram to understand it.
The Person interface has a few different sub-classes. This person interface and other sub-classes are not visible to the client. There is an intermediate class called PersonFactory that responsible for providing the correct instance based on the type argument. The client can get an instance by using the getPerson()
method.
Difference between Singleton pattern vs Factory method pattern
In the Factory pattern, you always use parameters to determine which instance you want to get. But the Singleton pattern works with the no-argument constructor.
When you use the Singleton pattern, you always know the type of instance which you are going to get. In the Factory pattern, Probably you don’t know the type of the instance.
You don’t see the instantiation logic of the Factory pattern. As our previous example, we don’t see the Person interface or its sub-classes. But the Singleton pattern, we can see the Singleton class and understand the implementation.
Real-world example for Factory pattern
A restaurant introduces three different promotions to increase customer attraction.
- Kottu Combo — Large Kottu + Pepsi
- Burger Combo — Burger + Pepsi
- Rice Combo — Large Rice + Pepsi
When a customer chooses the Combo type, the system will add the particular items according to the type of promotion.
Let’s see the UML class diagram for the scenario,
You can see the Promotion class and its sub-classes are hidden from the client. That’s why I introduced PromotionFactory to create instances with their PromotionCodes.
Now move on to the code,
First of all, let’s see the Food class and its sub-classes. Because the Promotion class creates a collection of Foods.
Food class,
Burger class,
The Kottu class, Rice class, and Pepsi class are also implemented as the Burger class. Actually, they are just empty classes with only the toString()
method.
Promotion class,
There are three things we need to implement in the Promotion class.
- Create a new ArrayList instance (foods).
- Implement an abstract method to create promotions (
createPromotion()
). - Call the
createPromotion()
method within the constructor.
BurgerComboPromotion class,
Here I override the createPromotion()
method. It is used to add foods to the foods ArrayList.
The implementation of RiceComboPromotion class and KottuComboPromotion class is the same as this.
PromotionCode enum,
These promotionCodes are used to map the correct instance. In other words, the user needs to pass this PromotionCode as an argument when he calls the getPromotion()
method.
PromotionFactory class,
Here we have a switch case to return the created instance. The client can call the getPromotion()
method to get an instance of the sub-classes of the Promotion class.
Application class (Client),
The client can get the instance by PromotionFactory class. Now you can understand the meaning of creating an instance without exposing the instantiation logic to the client.
Here it comes to the end of this article. I hope you learn something new about the Factory method pattern. If I miss some points, let me know in the comment section. Keep in touch. I will post other design patterns as well. Happy learning!