Factory Method Pattern

Stop Using new Everywhere
At some point, every codebase reaches this stage
if (type.equals("CAR")) {
return new Car();
} else if (type.equals("BIKE")) {
return new Bike();
} else if (type.equals("TRUCK")) {
return new Truck();
}
It works…
Until:
New types keep coming
The
if-elsekeeps growingOne change breaks many places
This is not a logic problem.
This is a creation problem — and that’s exactly where the Factory Method Pattern helps.
What Is the Factory Method Pattern?
Factory Method defines an interface for creating an object,
but lets subclasses decide which class to instantiate.
In simple words:
Move object creation out of business logic.
Instead of asking:
“Which class should I create?”
You say:
“Factory, give me what I need.”
The Core Problem It Solves
Without Factory:
Business logic knows concrete classes
Code is tightly coupled
Adding a new type means modifying existing code
With Factory:
Business logic depends on abstraction
Creation logic is centralized
New types = new classes (no modification)
Before Factory (Tight Coupling)
class NotificationService {
public Notification send(String type) {
if (type.equals("EMAIL")) {
return new EmailNotification();
} else if (type.equals("SMS")) {
return new SmsNotification();
}
return null;
}
}
Problems:
Violates Open/Closed Principle
Hard to test
Hard to extend
After Factory Method (Clean Design)
Step 1: Create a common interface
interface Notification {
void send();
}
Step 2: Concrete implementations
class EmailNotification implements Notification {
public void send() {
System.out.println("Sending Email");
}
}
class SmsNotification implements Notification {
public void send() {
System.out.println("Sending SMS");
}
}
Step 3: Factory Method
abstract class NotificationFactory {
abstract Notification createNotification();
}
Step 4: Concrete factories
class EmailFactory extends NotificationFactory {
Notification createNotification() {
return new EmailNotification();
}
}
class SmsFactory extends NotificationFactory {
Notification createNotification() {
return new SmsNotification();
}
}
Step 5: Client code (no new!)
NotificationFactory factory = new EmailFactory();
Notification notification = factory.createNotification();
notification.send();
Creation logic is completely separated from usage.
Simple Model
Think of a restaurant kitchen
You don’t decide how food is made
You just order the dish
The kitchen (factory) decides the process
Client → Factory → Product
Factory Method vs Simple Factory
| Simple Factory | Factory Method |
| Uses conditionals | Uses polymorphism |
| Single class | Multiple factories |
| Harder to extend | Easy to extend |
| Less flexible | More scalable |
Factory Method trades simplicity for extensibility.
When Should You Use Factory Method?
Use it when:
Object creation logic is complex
New types are expected
You want to follow OCP
You want loose coupling
Avoid it when:
Only one object type
No future extension
Overhead isn’t worth it
Don’t use Factory Method just because it exists.
Real-World Use Cases
Database drivers (
DriverManager)Logging frameworks
Payment gateways
UI components
Document parsers
SOLID Principles Used
SRP → Creation logic separated
OCP → Add new products without modification
DIP → Depend on abstractions
Factory Method is a SOLID-friendly pattern.
Summary
Problem → Too many `new`
Solution → Factory Method
Result → Flexible & scalable creation
Conclusion
Factory Method doesn’t remove object creation —
it puts it where it belongs.
Once we start using it, we’ll notice:
Logic becomes cleaner
Adding features feels safer



