Cover Image

In my last article about Factory Pattern, a simple and intuitive method was introduced to encapsulate product creation logic without exposing details. The problem is that once we add a new concrete product call we have to modify the Factory class. It is not very flexible and requires the factory depending all concrete product types. Although class registration techniques can be used to eliminate the couplings in some extent, they still have some major drawbacks that prevent them to be used extensively.

In this post, we will explore the more popular Factory Method Pattern that solves the above problems.

Before looking at how to solve the problems, let’s first introduce Factory Method design pattern.

Factory Method Pattern

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

Factory Method lets a superclass specifies all standard and generic behavior using virtul “placeholders” for creation steps, and then delegates the creation details to subcleasses that are supplied by the client. In other words, factory methods uses an abstract method that encapsulate object creation logic, thus the new operator which always creates an object is avoided.

Factory Methods are usually defined by an architectural framework, and then implemented by the user of the framework.

A Factory Method Example Diagram

Above example shows a CarFactory interface which has 3 concrete car factory types that implement CarFactory. They are BmwCarFactory, VolvoCarFactory and TeslaCarFactory, which produces BmwCar, VolvoCar and TeslaCar respectively. The client SimpleFactoryDemo asks a concrete car factory to create Car, without the need of coupling the concrete car type.

Here is an example of the usage.

1
2
3
public interface Car {
  void drive();
}
1
2
3
public interface CarFactory {
  Car create();
}

Above are the Car and CarFactory interfaces. Now let’s define the concrete product classes and their factories.

1
2
3
4
5
6
public class BmwCar implements Car {
  @Override
  public void drive() {
    System.out.println("Calling BmwCar::drive() method.");
  }
}
1
2
3
4
5
6
public class BmwCarFactory implements CarFactory {
  @Override
  public Car create() {
    return new BmwCar();
  }
}

As you can see above, the concrete factory class returns the abstract Car type instead of the concrete type.

Now let’s see how to use them in the client code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public class FactoryMethodDemo {

  public static void main(String[] args) {

    CarFactory carFactory1 = new BmwCarFactory();
    Car car1 = carFactory1.create();
    car1.drive();
  }

}

As shown above, the factory returns an abstract Car type, which is used afterwards. There is no need to couple the concrete product type to the client code.

Why use Factory Method Pattern?

The Factory Method Pattern is to solve the problem mentioned at the beginning of this article, which is the Simple Factory Pattern requires the factory to be updated whenever there is a new product type is added in the system.

So when to use a Factory Method Pattern instead of a Simple Factory Pattern? when your code requires multiple factory implementations. Each factory implementation implements the same factory interface, so that the products produced by the factories has the same abstract type, which makes the client code easy to switch factory implementations.

Pros and Cons?

Factory Method Pattern as explained above, has advantages in extensibility since it is more flexible in adding new types. It is a good example of open-closed principle in SOLID design principles.

Factory Method Pattern also has some drawbacks. As you might have noticed, factory method pattern requires you to create an interface for the Factory, and a factory implementation for each concrete factory. This leads to class explosions in amount when there are many types in a system.

Real Example

In Java, a good example is the iterator() method in the collection API, which is well stated in this article. Each collection implements the interface Iterable<E>, which defines a factory method iterator() that returns an Iterator<E>. An ArrayList<E> is a collection. So, it implements the interface Iterable<E> and overrides its factory method iterator() which returns a subclass of Iterator<E>.

Below is a simplifed definition of the Iterator<E> interface from the Java source code:

1
2
3
4
5
public interface Iterator<E> {
    boolean hasNext();
    E next();
    void remove();
}

Here is the factory interface:

1
2
3
public interface Iterable<T> {
    Iterator<T> iterator();
}

Below is a simplified definition of ArrayList from the java source code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class ArrayList<E> {
 //the iterator() returns a subtype and an "anonymous" Iterator<E>
 public Iterator<E> iterator()
   {
     return new Iterator<E>()
     {
    //implementation of the methods hasNext(), next() and remove()
     }
   }
...
}

As you can see above, this shows a concrete factory that implements a factory method iterator(). Note in actual Java source code, ArrayList is derived from AbstractList which is the one that implements the factory method pattern.

A typical use of the ArrayList and its iterator looks like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
 
public class Example {
    public static void main(String[] ars){
        // instantiation of the (concrete factory) ArrayList
        List<Integer> myArrayList = new ArrayList<>();
        
        // calling the factory method iterator() of ArrayList
        Iterator<Integer> myIterator = myArrayList.iterator();
    }
}

As shown above, the Iterator the ArrayList returns is an interface, thus the usage of it does not differ it from when getting from a LinkedList, a HashMap, a HashSet or any other Collection type. This is the power of this pattern: you don’t need to know what type of collections you’re using, each collection implementation will provide an Iterator through the factory method iterator().

Conclusion

Factory Method Pattern is a useful design pattern, when there are many concrete product types in the system, and may still be growing. Factory Method Pattern makes use of an abstract Factory interface and its factory method to have all concrete factory implementations produces the products with the same product type, thus encapsulates the producing details to the concrete factories themselves.

However, this pattern comes with the cost that it can expand the total number of classes in a system. Every concrete product class also requires a concrete factory class.