Skip to main content

Command Palette

Search for a command to run...

Factory Method Pattern

Published
•3 min read•View as Markdown
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-else keeps growing

  • One 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 FactoryFactory Method
Uses conditionalsUses polymorphism
Single classMultiple factories
Harder to extendEasy to extend
Less flexibleMore 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