Basics of Design Patterns — Factory Method 🏭

Martin Jurran
Software Design Patterns
6 min readJul 11, 2024

Factory Method is a customized assembly line for objects, usually referred to as products. It is a creational design pattern pattern which provides a unified interface for creating objects in a master class. Subclasses can define the types of objects that are being created.

You hired dedicated bakers (creators) for each type of product

Real-World Analogy 🌍

Imagine you’re turning your passion for baking into a business and opening a pastry shop in Jakarta.

Without design patterns, you (representing the business logic) would handle and fulfill all the orders yourself. That can be very strenuous, especially considering you want to sell a huge variety of products.

You are being overwhelmed with the variety of products to prepare

Using the Factory Method, you would have a specific Creator for each type of Product.

Let’s say you want to sell Croissants, Muffins, and Cheesecakes. Following this pattern, you decide to hire three specialized bakers right away, even though it’s against common advice.

You are outsourcing the creating of each product to dedicated bakers. Your task is to delegate work.

Now that you staffed up, you can delegate tasks. Your job is to take customer orders and assign them to the appropriate baker based on the order.

This approach makes your pastry shop scalable. For any new product, you just need to hire another specialized baker instead of learning to bake it yourself. Your main task is to manage and delegate.

Problem 🤔

Imagine that we are building a logistics and delivery management application for our pastry shop. At its initial release, the app can handle transport by car, so the majority of business logic resides inside the Car class.

After a while, your shop becomes more popular, and we need to introduce more delivery options. Each day, customers demand Grab, Uber or even Self-Pickup.

Adding a new class to the code is not easy if the existing code it directly coupled to one class only

That’s good for the business, but our application is struggling. Most code is bound to the Car class. Adding support for Grab would require changes to the entire codebase. All these changes are required again if new changes are requested.

In the end, we end up with an unmaintainable solution with extremely interdependent code full of conditionals that switch the solution’s behavior.

Solution 💡

The Factory Method pattern is a design principle that encourages developers to use a special factory method (e.g. createDeliveryMethod) instead of directly constructing objects with new.

Subclasses alter the object returned by the factory method createDeliveryMethod

The change may look like we just moved the constructor call from one part of the code to another. However, we can now override the factory method in subclasses and change the type of DeliveryMethod being created.

But: Subclasses can return different types, but only if they share a common base class or an interface. The factory method in the base class Delivery should have its return type declared as an interface.

The delivery classes are implementing the same interface DeliveryMethod

In this example, both Car and Pickup should implement the DeliveryMethod interface, which declares a method called Deliver. Each class has its own implementation of said method.

We can pass objects of a joint interface DeliveryMethod into the client code without breaking it

The code that utilized the factory method now doesn’t see a difference between the objects returned by various subclasses. The code handles all objects as aninterface of type DeliveryMethod. The client knows all objects are supposed to implement Deliver but doesn’t care about its inner workings.

Structure 🏗️

  1. Creator defines a Factory Method that returns objects matching the Product interface. This method can be forced through an abstract Creator class or interface to ensure consistency and modularity in code.
  2. Creator Implementations override the createProduct method to generate different types of objects that conform to the Product interface.
  3. Product interface is a standard interface used to define the commonalities of objects created by the Creator and its subclasses.
  4. Product Implementations are unique implementations of the Product interface that define specific behaviors and properties of an object.
// Define the Product interface
interface Product {
void PrintProduct();
}

// Define the ConcreteProductA that implements Product interface
class ConcreteProductA : Product {
public void PrintProduct() {
Console.WriteLine("This is Concrete Product A");
}
}

// Define the ConcreteProductB that implements Product interface
class ConcreteProductB : Product {
public void PrintProduct() {
Console.WriteLine("This is Concrete Product B");
}
}

// Define the Creator interface that defines the Factory Method
interface Creator {
Product CreateProduct();
}

// Define the Concrete Creator A that implements Creator interface
class ConcreteCreatorA : Creator {
public Product CreateProduct() {
return new ConcreteProductA();
}
}

// Define the Concrete Creator B that implements Creator interface
class ConcreteCreatorB : Creator {
public Product CreateProduct() {
return new ConcreteProductB();
}
}

// Application code to use the Factory pattern to create different objects
class Application {
static void Main() {
Creator creatorA = new ConcreteCreatorA();
Creator creatorB = new ConcreteCreatorB();

// Use the Factory Method to create Concrete Product A
Product productA = creatorA.CreateProduct();
productA.PrintProduct();

// Use the Factory Method to create Concrete Product B
Product productB = creatorB.CreateProduct();
productB.PrintProduct();
}
}

Pros and Cons

Pros

Decoupling. Avoid tight coupling between business logic and object creation by separating creator and products.

Single Responsibility Principle. Object creation is centralized in one part of the application, making it easy to maintain.

Open/Closed Principle. New products can be introduced into the code without requiring breaking changes.

Cons

Might overcomplicate things. A lot of new classes need to be introduced into the code.

Relation with other patterns

  • Abstract Factory, Prototype, or Builder patterns offer more flexibility but can be more complicated then Factory Method.
  • Abstract Factory uses a set of Factory Methods. Prototype can be used to compose these methods.
  • Factory Method can be used with Iterator to make collection subclasses return different types of compatible iterators.
  • Prototype doesn’t have inheritance-related drawbacks but requires a complicated initialization process for cloned objects. Factory Method is based on inheritance but doesn’t have initialization steps.
  • Factory Method is a specialization of Template Method pattern and can also serve as a step in a large Template Method.
  • Abstract Factory is a generalization of Factory Method, allowing for the creation of multiple families of related objects.
  • Singleton pattern can be implemented using the Factory Method pattern, as the Factory can be designed to only create a single instance of the object.
  • Builder pattern can be used along with the Factory Method pattern to create complex objects.
  • Strategy pattern can be used in conjunction with Factory Method, with the Factory selecting the appropriate strategy to use for a given task.

About this series

I noticed personally, that design patterns still remain a mistery to a lot of software engineers, even though these concepts are nothing new and have been around for decades.

I want to solve this problem with this article series to help other software engineers grow.

Feel free to comment in case you find mistakes or want to add your own perspective!

(Photo by the author, Illustrations by Takashi Mifune under free use)

--

--

Martin Jurran
Software Design Patterns

Personal blog of a Software Engineer | Azure DevOps, C#/.NET, JavaScript