In the previous article, we had an overview of the definition of design patterns, their categories and their importance in software development. In this article, let’s dive deeper into the first and widely used design pattern called “The Factory Method Pattern”.

What is the Factory Method Pattern?

Factory Method Pattern (or also called Factory Pattern for short) is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method – either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes – rather than by calling a constructor.

Problems

Imagine that you are the creator of a logistics management application called LogisticsApp. The first version of your app can only handle transportation by trucks, so the bulk of your current code is living inside the Truck class.

After a while, your app becomes pretty popular in the logistics community. Every day you receive dozens of requests from sea transportation companies to incorporate sea logistics into your application.

As the creator of the LogisticsApp, you are pretty happy with its current success. However, when thinking about the way to incorporate sea logistics code into your application, you suddenly realized that there are a bunch of problems waiting to be solved.

At present, the biggest problem is that most of your current code is already coupled to the Truck class. Adding Ship class into the application would require making changes to the entire codebase. Moreover, if later you decide to add another type of transportation to the app, you will probably need to make all of these changes again.

The Factory Method Pattern for developer
At present, adding a new class to the program is a big problem because the rest of the code is already coupled to the Truck class. Source: refactoring.guru

Solution

Luckily, there is a design pattern that can help you out with this problem, that is the Factory Method Pattern. According to its definition, the Factory Method Pattern suggests that you replace direct object construction calls (using the new operator) with calls to a special factory method. In reality, the objects are still created via the new operator, but it’s being called from within the factory method. Objects returned by a factory method are often referred to as “products.”

At first sight, this change may look pointless: we just moved the constructor call from one part of the program to another. However, consider this: now you can override the factory method in a subclass and change the class of products being created by the method.

Structure

The structure of the Factory Method Pattern consists of 4 important components: Product, concrete product(s), creator and concrete creator(s).

The Factory Method Pattern for developer
The structure of the Factory Method Pattern. Source: refactoring.guru
  • Product declares the interface, which is common to all objects that can be produced by the creator and its subclasses.
  • Concrete Products are different implementations of the product interface.
  • The Creator class declares the factory method that returns new product objects. It’s important that the return type of this method matches the product interface.
  • Concrete Creators override the base factory method so it returns a different type of product.

Note that the factory method doesn’t have to create new instances all the time. It can also return existing objects from a cache, an object pool, or another source.

When to Use the Factory Method Pattern?

The Factory Method Pattern really comes into plays when:

  • Don’t know ahead of time what class object you need.
  • You want to centralize the product creation code into one place in the program, making the code easier to support and interact with.
  • Wanting to encapsulate object creation and don’t want the user to have to know every subclass.

Solution to the LogisticsApp Problem

Let’s use the Factory Method Pattern to solve the problem of incorporating sea logistics into your LogisticsApp.

We can see that both truck and ship have the following similarities:

  • They are different types of transport
  • They all deliver something

With that in mind, we will create an interface called Transport, which will provide a deliver() method.

<?php
           interface Transport 
           {
                  public function deliver(): string;
           }
?>

Next, let’s create 2 concrete product classes called Truck and Ship. These classes both implements the Transport interface, so they all have to override the deliver method.

<?php
class Truck implements Transport 
{
       public function deliver(): string
       {
             return “Truck: Deliver by land in a box.”;
       }
}

class Ship implements Transport 
{
      public function deliver(): string
      {
            return “Ship: Deliver by sea in a container.”;
      }
}
?>
The Factory Method Pattern for developer
Source: refactoring.guru

After that, let’s create a creator class called Logistics, the main responsibility of this class is to provide createTransport() – an abstract method that returns an object that matches the Transport interface. The definition of it will be provided by concrete creator classes.

<?php
abstract class Logistics
{
      public function planDelivery(string $transportType): string
      {  
            $transport = $this->createTransport($transportType);
            echo $transport->deliver();

      }
      abstract public function createTransport(string $transporType): Transport;
}
?>

Finally, let’s create 2 concrete creator classes called RoadLogistics and SeaLogistics:

<?php
class RoadLogistics extends Logistics
{
        public function createTransport(string $transportType)
        {
                  if(strtolower($transportType) === strtolower(“Truck”)) {
                           return new Truck;
                  }
        }
}

class SeaLogistics extends Logistics 
{
         public function createTransport(string $transportType)
         {
                  if(strtolower($transportType) === strtolower(“Ship”)) {
                          return new Ship;
                  }
        }
}
?>

That’s it! We have completed setting up the Factory Method Pattern for our LogisticsApp. Let’s execute the code below to see the final result:

$roadLogistics = new RoadLogistics;
$seaLogistics = new SeaLogistics;

$transport = $roadLogistics->planDelivery(“Truck”);
$transport->delivery();

echo “\n”;

$transport = $seaLogistics->planDelivery(“Ship”);
$transport->delivery();

Result:

Truck: Deliver by land in a box.
Ship: Deliver by sea in a container.

Now, the code that uses the factory method (often called the client code) doesn’t see a difference between the actual products returned by various subclasses. The client treats all the products as abstract Transport. The types of logistics transportation (RoadLogistics, SeaLogistics) will determine the exact type of transport that will be used. Therefore, now you can add as many new types of transport as you want without bothering to unintentionally affect the existing codebase. Awesome! =D

The Pros and Cons of Factory Method Pattern

Pros

  • Factory Method Pattern helps prevent tight coupling between the creator and the concrete products.
  • With the Factory Method Pattern, you can centralize the product creation code into one place in the program, making the code easier to support and interact with.
  • By using the Factory Method Pattern, you can introduce new types of products into the program without breaking existing client code.

Cons

  • The code may become much more complicated since you will need to introduce a lot of new subclasses to implement the pattern.

Conclusion

In this article, we have learned a lot about the Factory Method Pattern. I hope that this design pattern will be a perfect solution to one of your software development problem sometime in the future.

In the next article of this series, we will learn about a brother of Factory Method Pattern called Abstract Factory Pattern. Stay tuned!

For further reading:

  1. https://refactoring.guru/design-patterns/factory-method
  2. https://en.wikipedia.org/wiki/Factory_method_pattern

Leave a Reply