Factory Method Pattern in Java (with Example)
The Factory Method pattern explained: centralise object creation behind a method that returns an interface, so adding a new type never touches the client. Java code, UML, Open/Closed, and when to use it.
🟢 Design Patterns · Creational · Fresher → 🟠senior
The Factory Method pattern answers a common frustration: your code is littered with new SomeClass(), and every time you add a new type you have to hunt down and edit all those spots. Factory Method centralises object creation behind a method, so what gets created can change without the calling code changing. It's one of the most-used patterns in real codebases — and a favourite interview answer for "how do I make this extensible?"
new directly, you call a factory method that decides which concrete class to instantiate and returns it as an interface — so adding a new type doesn't touch the client code.
The problem
Say you build notifications and start with email: new EmailNotification() scattered everywhere. Then you add SMS, then push. Now every creation site needs an if (type == EMAIL) … else if (type == SMS) …, repeated in many places. Adding "WhatsApp" means editing all of them — a clear Open/Closed violation. The creation logic is tangled into the business logic.
The solution
🟠Define a common interface, then put the "which class?" decision in a single factory. The client asks the factory for a product by name and works only with the interface — never the concrete classes.
interface Notification { void send(String msg); }
class EmailNotification implements Notification { public void send(String m){/*…*/} }
class SmsNotification implements Notification { public void send(String m){/*…*/} }
class NotificationFactory {
public Notification create(String type) { // the factory method
return switch (type) {
case "EMAIL" -> new EmailNotification();
case "SMS" -> new SmsNotification();
default -> throw new IllegalArgumentException(type);
};
}
}
// client — knows only the interface:
Notification n = factory.create("SMS");
n.send("hi");
Now the new logic lives in one place. Adding WhatsApp means writing a WhatsAppNotification class and adding one line to the factory — the client code that calls send() never changes.
Factory Method vs Simple Factory
🟠A nuance worth knowing. What we showed is often called a simple factory (one factory class with a switch). The textbook Factory Method goes further: the creation method is defined in a base class and overridden by subclasses, so each subclass decides what to create (e.g. a PDFDialog overrides createButton() to return a PDFButton). Both share the same goal — defer instantiation and centralise it — and in interviews either is a fine answer as long as you explain the intent.
Why it's good design
It embodies two SOLID ideas: Open/Closed (add a type by adding a class, not editing callers) and Dependency Inversion (clients depend on the Notification interface, not concrete classes). The result is loosely coupled, easily extended code — exactly what the pattern is for.
When to use it
🟠Reach for a factory when: object creation is non-trivial or repeated, you have a family of types behind one interface, or you want to hide which concrete class is used. If you have exactly one type and no plans for more, a plain new is fine — don't add a factory for its own sake.
The interview-ready summary
"Factory Method centralises object creation behind a method that returns an interface, so the client never calls new on a concrete class. That satisfies Open/Closed — adding a new type is a new class plus one line in the factory, with zero changes to callers — and Dependency Inversion. The strict GoF version defers creation to subclasses that override the factory method. I'd use it whenever creation logic is repeated or the concrete type should be swappable." Clean and clearly motivated."
What to read next
- Abstract Factory Pattern — factories for whole families of objects
- Builder Pattern — constructing complex objects step by step
- All Design Patterns (hub)
- ← The complete System Design guide (hub)