Factory Method Design Pattern

Introduction

Creational design patterns are concerned with the way of creating objects. These design patterns are used when a decision must be made at the time of instantiation of a class (i.e. creating an object of a class).

Factory design pattern is one of the most widely used creational design patterns. In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

It says that just define an interface or abstract class for creating an object but let the subclasses decide which class to instantiate. Simply put , the factory design pattern is used when we have a superclass with multiple sub-classes and based on input, we need to return one of the sub-class. This pattern takes out the responsibility of the instantiation of a class from the client program to the factory class.

Let us look at a real world example.

Factory pattern .png

In this example we will have an Animal interface that will have two methods : eat() and move(). (Since all animals can eat and move). Next we will have three implementations of this Animal interface : Tiger, Elephant and Panda. We will have a FactoryPatternDemo class that will use the getAnimal() method of the AnimalFactory class to get the object of the specific animal.

Lets define our Animal interface

Animal.java

public interface Animal {
    void eat();
    void move();
}

Next, we will write the implementations of our three animals : Tiger, Elephant and Panda.

Tiger.java

public class Tiger implements Animal 
{
    @Override
    public void eat() {
        System.out.println("Tiger::eat() : Tiger is eating");
    }

    @Override
    public void move() {
        System.out.println("Tiger::move() : Tiger is moving");
    }

}

Elephant.java

public class Elephant implements Animal 
{
    @Override
    public void eat() {
        System.out.println("Elephant::eat() : Elephant is eating");
    }

    @Override
    public void move() {
        System.out.println("Elephant::move() : Elephant is moving");

    }

}

Panda.java

public class Panda implements Animal{

    @Override
    public void eat() {
        System.out.println("Panda::eat() : Panda is eating");
    }

    @Override
    public void move() {
        System.out.println("Panda::move() : Panda is moving");
    }

}

Lets create our AnimalFactory class which will contain the getAnimal() method.

AnimalFactory.java

public class AnimalFactory 
{
    public Animal getAnimal(String animalType) {

        if(animalType == null) {
            return null;
        }

        if(animalType.equalsIgnoreCase("TIGER"))
        {
             return  new Tiger();
        }
        else if(animalType.equalsIgnoreCase("ELEPHANT"))
        {
             return new Elephant();
        }
        else if(animalType.equalsIgnoreCase("PANDA"))
        {
             return new Panda();
        }

        return null;
    }

}

Finally, to test out our code, we will use this Animal factory class in our FactoryPatternDemo class.

FactoryPatternDemo.java

public class FactoryPatternDemo 
{
    public static void main(String[] args) 
    {
        AnimalFactory animalFactory = new AnimalFactory();

        Animal animal1 = animalFactory.getAnimal("TIGER");
        animal1.eat();
        animal1.move();

        Animal animal2 = animalFactory.getAnimal("ELEPHANT");
        animal2.eat();
        animal2.move();

        Animal animal3 = animalFactory.getAnimal("PANDA");
        animal3.eat();
        animal3.move();
    }
}

On running the main() method , the output on the console will be :

Tiger::eat() : Tiger is eating
Tiger::move() : Tiger is moving
Elephant::eat() : Elephant is eating
Elephant::move() : Elephant is moving
Panda::eat() : Panda is eating
Panda::move() : Panda is moving

Benefits of Factory Pattern

  • Factory Method Pattern allows the sub-classes to choose the type of objects to create.
  • It promotes the loose-coupling by eliminating the need to bind application-specific classes into the code. That means the code interacts solely with the resultant interface or abstract class, so that it will work with any classes that implement that interface or that extends that abstract class.

One of the examples of Factory Pattern used in JDK is java.util.Calendar

static Calendar getInstance()
// Gets a calendar using the default time zone and locale.

static Calendar getInstance(Locale aLocale)
// Gets a calendar using the default time zone and specified locale.

static Calendar getInstance(TimeZone zone)
// Gets a calendar using the specified time zone and default locale.

static Calendar getInstance(TimeZone zone, Locale aLocale)
// Gets a calendar with the specified time zone and locale.

I hope you found the article useful.

Lets connect :

Happy Coding :) .