CHAPTER 07
Intermediate
Factory Method Pattern
Updated: May 16, 2026
30 min read
# CHAPTER 7
Factory Method Pattern
1. Introduction
Imagine you are building a logistics application. Initially, it only handles truck deliveries, so your code is filled withnew Truck(). A year later, your company becomes massively successful and adds sea deliveries. Now, you have to dig through your entire codebase, find every new Truck(), and wrap it in an if/else statement to handle new Ship(). This is fragile, tightly coupled code that violates the Open/Closed Principle. The Factory Method Pattern solves this. It provides a dedicated interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created. In this chapter, we will master the Factory Method, learning how to centralize the new keyword and build infinitely extensible creation architectures.
2. Learning Objectives
By the end of this chapter, you will be able to:- Define the core intent of the Factory Method Pattern.
-
Encapsulate the
newkeyword into dedicated creator classes.
- Understand the relationship between the "Creator" and the "Product" interfaces.
- Apply the Factory Method to adhere to the Open/Closed Principle (OCP).
- Refactor tightly coupled instantiation logic into dynamic factories.
3. The Core Concept
The Factory Method suggests that you replace direct object construction calls (using thenew operator) with calls to a special *factory method*.
- The Decoupling: The objects returned by a factory method are often referred to as *products*. Your business logic only interacts with the *Product Interface*, not the concrete classes.
-
The Strategy: You create an abstract
Logisticsclass with acreateTransport()factory method. TheRoadLogisticssubclass implements the method to return aTruck. TheSeaLogisticssubclass implements it to return aShip.
4. Creators and Products
The pattern relies on two parallel inheritance hierarchies.-
1.
The Products: The interface (
Transport) and the concrete objects (Truck,Ship) that do the actual work.
-
2.
The Creators: The abstract class (
Logistics) that declares the factory method, and the concrete factories (RoadLogistics,SeaLogistics) that execute thenewkeyword.
5. Why is this better?
-
Single Responsibility (SRP): The code that decides *how* to create a complex
Truckis moved out of the business logic and isolated inside the factory.
-
Open/Closed Principle (OCP): If you need to add Air Deliveries, you DO NOT touch the existing code. You simply create a new
Planeproduct and a newAirLogisticscreator. The system is infinitely extensible.
6. UML Diagram
*Factory Method Structure*
text
7. Code Example (PHP)
Let's implement the Logistics example.
php
8. Best Practices
-
Parameterized Factories (Simple Factory): Sometimes, creating a full inheritance hierarchy of Creators is overkill. A common variant is the "Simple Factory" (technically not the GoF Factory Method, but widely used). This is a single class with a method like
createVehicle($type)containing aswitchstatement that returnsnew Truck()ornew Ship(). Use this for simpler logic.
9. Common Mistakes
-
The Empty Creator: If your
Logisticsbase class *only* contains the factory method and has zero other business logic (likeplanDelivery()), you don't really need the Factory Method pattern. You are likely over-engineering. The true power of the Factory Method is when the base class has complex, shared business logic that relies on an object that its subclasses must define.
10. Mini Project: Build a Notification Factory
-
1.
Products: Create a
Notificationinterface with asend($msg)method. CreateEmailNotificationandSMSNotificationclasses.
-
2.
Creators: Create a simple
NotificationFactoryclass.
-
3.
Logic: Create a static method
create($type). If$type == 'email', return a new Email object.
-
4.
Action: From your main script, generate both an Email and an SMS using the factory, and call
send(). Notice how thenewkeyword never appears in your main script.
11. Practice Exercises
- 1. Explain how the Factory Method Pattern specifically enforces the Open/Closed Principle (OCP) when adding a new type of product to the system.
- 2. Describe the difference between the "Creator" classes and the "Product" classes in the Factory Method UML architecture.
12. MCQs with Answers
Question 1
In the Factory Method pattern, the client code (business logic) interacts with the newly created objects exclusively through:
Question 2
What is the primary architectural benefit of moving the new keyword out of your main business logic and into a dedicated Factory class?
13. Interview Questions
- Q: Explain the difference between the formal Gang of Four "Factory Method Pattern" and the common idiom known as a "Simple Factory" (a single class with a massive switch statement).
-
Q: In a massive enterprise application, walk me through a scenario where hardcoding the
newkeyword for database models deep within your controllers would create a testing nightmare. How does the Factory pattern resolve this?
-
Q: Look at this code containing a complex
if/elseblock creating 5 different types of enemy characters in a video game. Refactor it on the whiteboard using the Factory Method pattern.
14. FAQs
Q: Can a Factory return an existing object instead of creating a new one? A: Yes! That is a massive advantage of using a Factory. You can combine a Factory with a Cache (or a Singleton). WhencreateProduct() is called, the Factory can check if the object is already in memory. If so, return it; if not, use new. The client code never knows the difference.
15. Summary
In Chapter 7, we engineered a dynamic assembly line. We recognized that hardcoding instantiation with thenew keyword creates brittle, tightly coupled architecture that breaks the Open/Closed Principle. By deploying the Factory Method Pattern, we successfully isolated the complex logic of object creation into dedicated Creator classes. Our business logic now floats cleanly above the implementation details, interacting purely with Product Interfaces. This pattern allows us to infinitely extend our systems with new object types without ever rewriting existing code.