Factory Method Pattern

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.

Concept

In factory method pattern, we create an abstract creator class that defines a basic structure of application and the subclasses which derive from this abstract class perform the actual instantiation process. The concept makes more sense to you as you read through the analogy, class diagrams and examples.

Factory method pattern is the extension of simple factory pattern

Read about simple factory pattern

In the simple factory pattern, we simply segregate the instantiation logic from client code where it knows about all the classes whose objects it can create.

On the other hand, when using a factory method pattern, you delegate the object creation to subclasses. Also, the factory method is not absolutely sure about the product subclasses in advance.

Note: The key aim of the factory method pattern is that it is supplying the framework through which different subclasses can make different products. But in a simple factory, you cannot vary the products like you can with the factory method pattern.

Think of simple factory as a one-time deal but most importantly, your creational part will not be closed for modification. Whenever you want to add a new stuff, you need to add an if..else block or a switch statement in the factory class of your simple factory pattern.

In this context, remember the GoF definition - the factory method lets a class defer instantiation to subclasses. So, in our simple factory pattern demonstration, you used a concrete class only (SimpleFactory). You did not need to override the createAnimal() method and there was no subclass that participated in the final decision/product making process. But if you try to code to an abstract class (or interface), that is always considered a good practice, and this mechanism provides you the flexibility to put some common behaviors in the abstract class.

Analogy

Consider a car manufacturer who produces the different car models as per customer preferences. For different car models, manufacturer uses different parts. In the future, the manufacturer should be able to replace the car parts with newly designed models. This is the perfect analogy of factory method pattern. Here, CarFactory can be the abstract factory and each factory model extends CarFactory.

Implementation In Java

Factory method pattern is the extension of simple factory pattern. Let’s extend the same example from simple factory pattern.

Class Diagram

Factory pattern has two parallel hierarchies. One for factory classes and another for object producing classes.

In our case, classes in factory method pattern incudes,

classDiagram

  class Client {
    +process()
  }

  class AnimalFactory {
    +AnimalFactory()
    +createAnimal()* Animal
  }

  class DogFactory {
    +DogFactory()
    +CreateAnimal() Animal
  }

  class CatFactory {
    +CatFactory()
    +CreateAnimal() Animal
  }

  class Animal {
    <<interface>>
    +speak()
    +eat()
  }

  class Dog {
    +Dog()
    +speak()
    +eat()
  }

  Client --> AnimalFactory
  AnimalFactory --|> DogFactory
  AnimalFactory --|> CatFactory
  
  Animal <|-- AnimalFactory

  Animal <|.. Dog
  Animal <|.. Cat

Illustration

In the above class diagram, there are two class hierarchies. One class hierarchy is for AnimalFactory related classes and another is for Animal related classes.

AnimalFactory classes uses Animal classes to create objects as client specified.

AnimalFactory is an abstract class. DogFactory and CatFactory extends AnimalFactory and implements createAnimal() method.

Animal classes is an interface. Dog and Cat implements the speak() and eat() methods as they implements Animal.

Client uses concrete factory classes like CatFactory and DogFactory to create Animal type objects (Dog and Cat).

Implementation

Following code blocks are the classes implementations for factory method pattern

AnimalFactory

AnimalFactory.java implementation

abstract class AnimalFactory {
    //  abstract factory to create animal
    public abstract Animal createAnimal();
}

DogFactory

DogFactory.java implementation

class DogFactory extends AnimalFactory {

    //  creates dog object
    @Override
    public Animal createAnimal() {
        return new Dog();
    }
}

CatFactory

CatFactory.java implementation

class CatFactory extends AnimalFactory {

    //  creates cat object
    @Override
    public Animal createAnimal() {
        return new Cat();
    }
}

Animal

Animal.java implementation

interface Animal {

    //  interface methods
    void speak();

    //  interface default method
    default void eat() {
        System.out.println("Yum! Yum!");
    }
}

Dog

Dog.java implementation

class Dog implements Animal{

    //  Dog implementation extends Animal
    public Dog() {}

    @Override
    public void speak() {
        System.out.println("Bow! Bow!");
    }
}

Cat

Cat.java implementation

class Cat implements Animal{

    //  Cat implementation extends Animal
    public Cat() {}

    @Override
    public void speak() {
        System.out.println("Meow! Mewo!");
    }
}

Client

Client.java implementation

class Client {
    public void process() {
        AnimalFactory dogFactory = new DogFactory();
        Animal dog = dogFactory.createAnimal();
        dog.speak();
        dog.eat();

        AnimalFactory catFactory = new CatFactory();
        Animal cat = catFactory.createAnimal();
        cat.speak();
        dog.speak();
    }
}

Reason for creating createAnimal() method in Client class is intentional. The intention is to create specialized objects using subclasses.

If we look carefully, only the creational part is varying across the products.

Advantages

  • Separating code that can vary from the code that does not vary (i.e., the advantages of using a simple factory pattern is still present). This technique helps you easily maintain code.

  • The code is not tightly coupled. So, you can add new classes like Lion, Beer, and so forth, at any time in the system without modifying the existing architecture. So, you have followed the closed for modification but open for extension principle.

Disadvantages

  • The factory method pattern involves creation of many classes. If the number of classes increases, it can add up the code maintenance efforts.

When To Use

  • When client does not know which class it may require at runtime.
  • A class wants its subclasses to specify the objects it creates.
  • When you want to encapsulate the object creation process.
  • Object instance needs to be initialized with some data is not available to the client.
  • Object instantiation requires a lot of data and there are a lot of variations based on the data. Instead, proved static factory methods that create the instance based on the different variations.

Known Uses

Factory method pattern is used in many frameworks and is also incorporated into core language structure.

Java

Following are the factory method examples used in java language.

java.util.Calendar#getInstance()
java.util.ResourceBundle#getBundle()
java.text.NumberFormat#getInstance()
java.nio.charset.Charset#forName()
java.net.URLStreamHandlerFactory#createURLStreamHandle (String) // Returns singleton object per protocol
java.util.EnumSet#of()
javax.xml.bind.JAXBContext#createMarshaller() // and other similar methods
  • The factory Method has a lot of variations. It can return a new object or same instance multiple times, or can return a subclass object by extending a new class.
  • Factory Method is usually called through the template method and is usually a hook that subclasses can override for custom implementation.
  • Used to implement abstract factory.
  • Factory method has to be subclasses if it has to return a new object. Prototype pattern don’t require a new class. It requires a new object.
  • Prototype pattern require initialize operations after returning an instance. Factory method don’t require such operation.

Subscribe For More Content