DateOct 19, 2022

Factory Method Design Pattern

🚧
This post is for anyone developing a codebase based on the Object-Oriented Paradigm. This post is Language agnostic and the learnings have an implementation across all OOP-based languages.

In the previous post of this Design series, we learned about the Singleton Design Pattern - What is it? How to use it? When to use it?

In this post, let's look at another Creational Design pattern - Factory Method Design Pattern.

Introduction

Problem Statement

Before we look at the implementation of this pattern, first we need to understand the utility of this pattern and what kind of problem are we trying to solve?

Imagine you are owner of Tesla (Bye Elon!). When you cofounded the company, you decided to create only cars. Hence your code only has one Car class where you are maintaining all the attributes and methods.

However, one day you have decided to manufacture the Tesla Pickup Truck. Now what you will do? Create another Truck class and try to make it work along with the Car class. But what if tomorrow, you wish to add a Tesla Bike or a Airplane and so on and so forth. Soon your code will become a pile of mess! which changes behaviour based on the vehicle type.

This is where the Factory Method pattern comes into picture.

👉🏼
Factory Method is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.

Factory Method Pattern to Rescue

The Factory method pattern allows us to replace the direct class instantiation with a "Factory" which returns back us the object as per our needs. This objects are often know as "products" of the factory.

👉🏼
One thing you need to understand is that all the subclasses can return same type of "product" only if the subclasses are extension of implementation of another class and interface respectively. Also the factory method should have its return type declared as this interface.
Example of Factory Design Pattern
Example of Factory Design Pattern

Components of Factory Design Pattern

  1. Factory Interface - Implemented by the different Product Factories.
  2. Factory Concrete Classes - Implement the Factory Interface and contain the respective Product Instantiation Logic based on certain conditions.
  3. Product Interface - Implemented by the product concrete classes.
  4. Product Concrete Classes - Concrete implementation of the product classes. These are used by the Concrete Factory Classes to return the respective product object.

Implementation

Let's take the previous example to discuss the implementation -

Product Interface - Vehicle.java

package factoryDesign;

public interface Vehicle {
    void move();
    void turn();
}

Product Concrete Classes

Car.java

package factoryDesign;

public class Car implements Vehicle {

    public Car() {
    	System.out.println("Hi! I am a car!");
    }

    public void move() {
        System.out.println("Car Moves");
    }

    public void turn() {
        System.out.println("Car Turns");
    }
}

Truck.java

package factoryDesign;

public class Truck implements Vehicle {

    public Truck() {
    	System.out.println("Hi! I am a Truck!");
    }

    public void move() {
        System.out.println("Truck Moves");
    }

    public void turn() {
        System.out.println("Truck Turns");
    }
}

Factory Interface - VehicleFactory.java

package factoryDesign;

import Vehicle;

public interface VehicleFactory {
	public Vehicle getVehicle(String vehType);
}

Factory Concrete Classes

CarFactory.java

package factoryDesign;

import Vehicle;

public class CarFactory implements VehicleFactory {
	public Vehicle getVehicle(String vehType) {
		Vehicle vehicle = new Car();
		return vehicle;
	}
}

TruckFactory.java

package factoryDesign;

import Vehicle;

public class TruckFactory implements VehicleFactory {
	public Vehicle getVehicle(String vehType) {
		Vehicle vehicle = new Truck();
		return vehicle;
	}
}

Usability

  • Use the Factory Method when you don’t know beforehand the exact types and dependencies of the objects your code should work with.
  • Use the Factory Method when you want to provide users of your library or framework with a way to extend its internal components.
  • Use the Factory Method when you want to save system resources by reusing existing objects instead of rebuilding them each time.