DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • How Large Tech Companies Architect Resilient Systems for Millions of Users
  • Building Security into the Feature During the Design Phase
  • Build a Scalable E-commerce Platform: System Design Overview
  • A Step-by-Step Guide to Write a System Design Document

Trending

  • How To Develop a Truly Performant Mobile Application in 2025: A Case for Android
  • Fixing Common Oracle Database Problems
  • Integrating Security as Code: A Necessity for DevSecOps
  • AI-Powered Professor Rating Assistant With RAG and Pinecone

Creational Design Pattern Series: Factory Method Pattern

Learn more about your favorite design pattern — the factory method pattern.

By 
Swathi Prasad user avatar
Swathi Prasad
·
Feb. 11, 19 · Presentation
Likes (13)
Comment
Save
Tweet
Share
18.9K Views

Join the DZone community and get the full member experience.

Join For Free

The factory method design pattern is one of the well-known “Gang of Four” (GoF) design patterns. It is a creational design pattern that uses factory methods to deal with creating instances without specifying the exact class of the object that will be created.

This design pattern is based on one of the OOPs concepts, which is encapsulation. In general, we write object creation code on client side programs, but in the factory pattern, we encapsulate object creation code inside the factory method. So, depending on the data provided to the factory, it can return an object of one of several possible classes listed within a program.

In this article, let us look at a small but complete example of the Factory Pattern.

The pattern basically works as shown below in the UML diagram:

Factory Method Design Pattern

A Person Interface

First, let’s create a Person interface. Any Person that the factory returns must implement this Java interface. We’ll just specify that any class that calls itself a Person must implement a run method.

public interface Person {
    public void run();
}


Concrete Classes

We will create three concrete classes that implement the Person interface. This is an important part of the Factory Pattern.

Note that the Super class in the factory method pattern can be an interface, abstract class, or normal class.

public class ConcretePersonA implements Person {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConcretePersonA.class);

    public void run() {
        LOGGER.info("{} running",ConcretePersonA.class.getSimpleName());
    }
}


public class ConcretePersonB implements Person {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConcretePersonB.class);

    public void run() {
        LOGGER.info("{} running",ConcretePersonB.class.getSimpleName());
    }
}


public class ConcretePersonC implements Person {

    private static final Logger LOGGER = LoggerFactory.getLogger(ConcretePersonC.class);

    public void run() {
        LOGGER.info("{} running", ConcretePersonC.class.getSimpleName());
    }
}


The Factory Class

Let’s define a Factory class, which is a  PersonFactory class. As you can see from the code below, the PersonFactory  has a staticgetPerson method that returns a Person that depends on the type that has been provided.

public class PersonFactory {

    public static Person getPerson(String type)
    {
        if ("BaseRun".equals(type)) {
            return new ConcretePersonA();
        }
        else if ("LongRun".equals(type) ) {
            return new ConcretePersonB();
        }
        else if ("ProgressionRun".equals(type) ) {
            return new ConcretePersonC();
        }
        return null;
    }
}


Here, the signature of the factory method states that it will be returning a class of type Person. The factory doesn’t say it’s returning a ConcretePersonA,  ConcretePersonB, or ConcretePersonC — it just says it’s returning something that implements the Person interface.

Running the Example

Now that we created a Person factory, the Person interface, and all the concrete persons that implement this interface. We will now create a “driver” program, FactoryPattern , to test the Person factory.

public class FactoryPattern
{
    public static void main( String[] args )
    {
        Person person = PersonFactory.getPerson("BaseRun");
        person.run();

        person = PersonFactory.getPerson("LongRun");
        person.run();

        person = PersonFactory.getPerson("ProgressionRun");
        person.run();
    }
}


Here, we created an instance of each type of Person.

Conclusion

The main reason the factory pattern is used is that it introduces weak coupling instead of tight coupling, hiding concrete classes from the application. It provides customization hooks and the implementation comfortably accommodates new changes.

The factory must be used for a family of objects. If the classes doesn't extend a common base class or interface, they cannot be used in a factory design template.

The source code can be found in my GitHub repository.

In the next post, we will look at the Abstract Factory design pattern.

Factory (object-oriented programming) Factory method pattern Design

Published at DZone with permission of Swathi Prasad, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • How Large Tech Companies Architect Resilient Systems for Millions of Users
  • Building Security into the Feature During the Design Phase
  • Build a Scalable E-commerce Platform: System Design Overview
  • A Step-by-Step Guide to Write a System Design Document

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: