Understand the Factory Method Pattern in Java

Noel KAMPHOANoel KAMPHOA
3 min read

1. Introduction

In object-oriented programming, the Factory Method Pattern is a widely used creational design pattern that provides a robust solution for object instantiation. Instead of creating objects directly using constructors, this pattern suggests using factory methods to encapsulate the instantiation logic.

According to the Gang of Four (GoF),

"Factory Method lets a class defer instantiation to subclasses."

This design principle encourages loose coupling, flexibility, and adherence to the Open/Closed Principle—a cornerstone of clean code.

In this article, we will explore how the Factory Method Pattern works in Java, its benefits, and practical use cases. If you’re new to design patterns, consider reading our introduction to the SOLID principles for foundational context.

2. What Is the Factory Method Pattern?

The Factory Method Pattern defines an interface for creating an object, but allows subclasses to alter the type of objects that will be created. Rather than calling a constructor directly, a method (often named create or getInstance) is used to encapsulate the logic of object creation.

Key Characteristics

  • Delegates the instantiation logic to subclasses or factories

  • Encourages adherence to programming to interfaces, not implementations

  • Supports open-closed design by making it easy to introduce new product types

This pattern is especially useful in frameworks, plugins, and systems where the exact class of the object to be created isn't known until runtime.

3. Core Components

The pattern typically consists of:

  • Product: An interface or abstract class that declares the common behavior.

  • ConcreteProduct: Specific implementations of the Product interface.

  • Creator: An abstract class or interface declaring the factory method.

  • ConcreteCreator: Subclasses that implement the factory method to return instances of ConcreteProduct.

Understanding these components helps reinforce key OOP principles like abstraction and inheritance.

4. Example Implementation

Let’s consider a notification system that can send messages via Email or SMS. Instead of hard-coding object creation, we use a factory method to determine which notification service to instantiate.

// Product interface
public interface Notification {
    void notifyUser();
}
// ConcreteProduct implementations
public class EmailNotification implements Notification {
    public void notifyUser() {
        System.out.println("Sending an Email notification");
    }
}

public class SMSNotification implements Notification {
    public void notifyUser() {
        System.out.println("Sending an SMS notification");
    }
}
// Creator with factory method
public abstract class NotificationFactory {
    public abstract Notification createNotification();
}
// ConcreteCreators
public class EmailFactory extends NotificationFactory {
    public Notification createNotification() {
        return new EmailNotification();
    }
}

public class SMSFactory extends NotificationFactory {
    public Notification createNotification() {
        return new SMSNotification();
    }
}

Client Code

NotificationFactory factory = new EmailFactory();
Notification notification = factory.createNotification();
notification.notifyUser(); // Output: Sending an Email notification

This structure makes it easy to add new notification types without modifying the existing codebase, aligning with good design practices.

5. Advantages of the Factory Method Pattern

  • Loose Coupling: Classes depend on abstractions, not concrete implementations.

  • Scalability: New types can be added without changing existing code.

  • Code Clarity: Encapsulating creation logic simplifies client-side usage.

  • Enhanced Testing: Easier to mock and substitute implementations.

As your codebase grows, these benefits become increasingly significant.

6. Use Cases in Real Projects

  • Logging frameworks (e.g., log4j) use factory methods to create loggers.

  • GUI toolkits create widgets depending on the platform.

  • Connection factories in database access layers.

Wherever object creation logic needs to vary, the Factory Method Pattern offers an elegant solution.

7. Conclusion

The Factory Method Pattern in Java promotes clean code and flexible architecture by decoupling object creation from usage. It allows developers to design scalable and maintainable systems, especially in plugin-driven or layered applications.

You can find the complete code of this article here on GitHub.

Originally published on my blog at https://nkamphoa.com/factory-method-pattern-in-java/

0
Subscribe to my newsletter

Read articles from Noel KAMPHOA directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Noel KAMPHOA
Noel KAMPHOA

I’m a senior Java developer with 13+ years of experience building scalable applications using Java, Spring Boot, and Angular. While my main role is in software engineering, I also write weekly tutorials on nkamphoa.com — a side project where I share tools, techniques, and real-world insights for Java learners and practitioners. Topics I regularly cover include: ✔Java SE learning path (from beginner to expert) ✔Modern Java tools & libraries ✔Practical projects & debugging strategies