The Factory Method is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created. It helps achieve loose coupling and promotes the Open-Closed Principle (OCP) in object-oriented design.
In this post, we'll explore the Factory Method pattern using a fun and easy-to-understand example: creating different types of drinks! βπ₯€
Why Use the Factory Method?
β
Encapsulation β The creation logic is hidden from the client.
β
Flexibility β New types of objects can be added without modifying existing code.
β
Loose Coupling β The client code depends only on an abstract interface, not concrete classes.
Example: A Drink Factory π₯€
Imagine we have a drink shop that serves Tea, Coffee, and Soda. Instead of manually creating each drink in different parts of the code, we'll use the Factory Method to centralize and simplify object creation.
Step 1: Define an Interface for Drinks
We create a common interface Drink
that all drink types will implement.
public interface Drink {
void prepare();
}
Step 2: Create Concrete Drink Classes
Each drink class implements the Drink
interface and defines its own preparation method.
public class Tea implements Drink {
@Override
public void prepare() {
System.out.println("Boiling water, adding tea leaves, and serving tea.");
}
}
public class Coffee implements Drink {
@Override
public void prepare() {
System.out.println("Brewing coffee, adding sugar and milk, and serving coffee.");
}
}
public class Soda implements Drink {
@Override
public void prepare() {
System.out.println("Pouring soda into a glass and adding ice.");
}
}
Step 3: Create the Factory Method
Now, we implement a DrinkFactory that will be responsible for creating drink objects based on a given type.
public class DrinkFactory {
public static Drink createDrink(String type) {
switch (type.toLowerCase()) {
case "tea":
return new Tea();
case "coffee":
return new Coffee();
case "soda":
return new Soda();
default:
throw new IllegalArgumentException("Unknown drink type: " + type);
}
}
}
πΉ Note: We used a switch statement for simplicity, but a more scalable approach would be implementing the Strategy Pattern instead.
Step 4: Using the Factory in the Main Program
Now, let's see how we can use our DrinkFactory
to create drinks dynamically.
public class FactoryMethodExample {
public static void main(String[] args) {
Drink tea = DrinkFactory.createDrink("tea");
Drink coffee = DrinkFactory.createDrink("coffee");
Drink soda = DrinkFactory.createDrink("soda");
tea.prepare();
coffee.prepare();
soda.prepare();
}
}
Output:
Boiling water, adding tea leaves, and serving tea.
Brewing coffee, adding sugar and milk, and serving coffee.
Pouring soda into a glass and adding ice.
Pros and Cons of the Factory Method Pattern
β Pros:
β Encapsulation β The object creation logic is hidden from the client.
β Scalability β New drink types can be added without changing client code.
β Code Reusability β The factory centralizes object creation, making maintenance easier.
β Cons:
β More Classes and Complexity β Introducing a factory adds extra classes.
β Difficult to Understand at First β Beginners might find it harder to follow compared to simple object instantiation (new Tea()
).
Common Use Cases for Factory Method
The Factory Method is widely used in real-world applications:
β GUI Frameworks (e.g., creating different button types)
β Database Connections (e.g., connecting to MySQL, PostgreSQL, etc.)
β Logging Systems (e.g., different log levels or outputs)
β Parsing Documents (e.g., handling JSON, XML, etc.)
Conclusion
The Factory Method is a powerful pattern that improves code maintainability and flexibility. While we used a switch statement for simplicity, a better approach for scalability would be implementing the Strategy Pattern to handle different drink types dynamically.
Top comments (0)