Creational Design Pattern Series: Factory Method Pattern

Factory method design pattern is one of the well-known “Gang of Four” (GoF) design patterns and 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 concept that is encapsulation. In general, we write object creation code on client side program but in factory pattern, we encapsulate object creation code inside 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 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 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 or 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 static getPerson 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 person factory, the Person interface, and all the concrete persons that implement this interface. We will now create a “driver” program that is 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 for which 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 don’t extend 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 Abstract Factory design pattern.

Advertisements