Understanding Design Patterns: Factory-Method
Tags: javascript, designpatterns, cleancode, typescript
Published: 2021-01-13 10:23:02

---
title: Understanding Design Patterns: Factory-Method
published: true
description: In this article, I am going to describe how the **Factory-Method Pattern** works and when it should be applied.
tags: javascript, designpatterns, cleancode, typescript
cover_image: https://cdn-images-1.medium.com/max/1200/1*2xkuAV6TKPdO8sXRPdlG6Q.jpeg
canonical_url: https://www.carloscaballero.io/understanding-design-patters-factory-method
series: pattern-design
---


There are 23 classic design patterns which are described in the original book `Design Patterns: Elements of Reusable Object-Oriented Software`. These patterns provide solutions to particular problems often repeated in software development.

In this article, I am going to describe how the **Factory-Method Pattern** works and when it should be applied.

---


# Factory-Method: Basic Idea

>  The ***factory method pattern*** is a [creational pattern](https://en.wikipedia.org/wiki/Software_design_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 — [Wikipedia](https://en.wikipedia.org/wiki/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  — Design Patterns: Elements of Reusable Object-Oriented Software

On many occasions we need to create different types of objects that are not known a priori from a list of possible objects. The natural tendency is to create a `factoryManager` class that allows us to obtain the different types of objects based on a parameter. However, this solution has two serious drawbacks that we will describe throughout this article:

1. It breaks the principle of *Open-Closed Principle* which leads to code that is not clean; and that it is not easy to maintain when the software scales.

2. The `factoryManager` class is attached to all types of objects that you want to build, creating code known as `spaghetti code`.

The following code shows the classic problem in which there is a `create` method that returns an object of a type based on a parameter pass as an argument:

```javascript
function create(type) {
  switch(type){
    case '0': return new Object1();
    case '1': return new Object2();
    case '2': return new Object3();
    default: return new Object4();
  }
}
```

The **Factory-Method** pattern allows for clearer code, since it avoids the problem raised above. The UML diagram of this pattern is as follows:

![UML Diagram from Design Patterns: Elements of Reusable Object-Oriented Software book.](https://cdn-images-1.medium.com/max/3658/1*n7p-k_qujk5DGIQhKItfww.png)

The classes that make up this pattern are the following:

* **Product** it is the common interface of all objects that can be created.

* **ConcreteProductOne** and **ConcreteProductTwo** are implementations of the `Product` interface.

* **Creator** is an abstract class in which the `factoryMethod` method is declared, which will be responsible for generating an object of type `Product`. The concrete implementation of the object is not carried out by this class, but responsibility is delegated to the `ConcreteCreator1` and `ConcreteCreator2` classes.

* **ConcreteCreator1** and **ConcreteCreator2** override the `factoryMethod` with the creation of the concrete object.

It is important to clarify several points that are often misunderstood as a result of the name of this pattern:

 1. This pattern does not implement a `factory` method that is responsible for creating specific objects. Rather, the responsibility is delegated to the subclasses that implement the abstract class.

 2. This pattern is a specific case of the **[Template-Method pattern] (http://www.carloscaballero.io/design-patterns-template-method/)**, in which it delegates the responsibility of variants in an algorithm to concrete classes. In the case of the **Factory-Method** pattern, the responsibility of creating objects is being delegated to the classes that implement the interface.

3. The `factoryMethod` **method does not have to create new instances every time**, but can return these objects from a memory cache, local storage, etc. What is important is that this method must return an object that implements the `Product` interface.

# Factory-Method Pattern: When To Use

1. The problem solved by the pattern **Factory-Method** is easy to identify: **The object with which the client must work is not known a priori**, but this knowledge depends directly on the interaction of another user with the system (end-user or system). The traditional example where the need for this pattern arises is when the user selects an object type from a list of options.

2. In the event that **it is necessary to extend the internal components** (the number of objects that are created) without the need to have the code attached, but instead there is an interface that must be implemented and it should only be extended by creating a class relative to the new object to be included and its specific creator.

# Factory-Method Pattern: Advantages and Disadvantages

The *Factory-Method* pattern has a number of advantages that can be summarized in the following points:

* The code is more maintainable because it is less coupled between the client classes and their dependencies.

* **Clean code** since the *Open-Closed Principle* is guaranteed due to new concrete classes of `Product` can be introduced without having to break the existing code.

* **Cleaner code** since the *Single Responsibility Principle (SRP)* is respected because the responsibility of creating the concrete `Product` is transferred to the concrete creator class instead of the client class having this responsibility.

However, the main drawback of the *factory-method* pattern is the increased complexity in the code and the increased number of classes required. This a well-known disadvantage when applying design patterns — the price that must be paid to gain abstraction in the code.

---


# Factory-Method pattern examples

Next we are going to illustrate two examples of application of the *Factory-Method* pattern:

1. Basic structure of the **Factory-Method pattern**. In this example, we'll translate the theoretical UML diagram into TypeScript code in order to identify each of the classes involved in the pattern.

2. A Point of Service (POS) of a fast food restaurant in which the *Factory-Method pattern* will be incorrectly applied resulting in a software pattern (not by design) known as *Simple-Factory* in which the *Open-Closed Principle* is not respected. However, this programming technique is really useful when no more abstraction is required than necessary. Although, the price to pay is high when you want to scale the project.

3. Resolution of the previous problem applying the *Factory-Method pattern*.
  

The following examples will show the implementation of this pattern using TypeScript. We have chosen TypeScript to carry out this implementation rather than JavaScript — the latter lacks interfaces or abstract classes so the responsibility of implementing both the interface and the abstract class would fall on the developer.

---
# Example 1: Basic Structure of the Factory-Method Pattern

In this first example, we’re going to translate the theoretical UML diagram into TypeScript to test the potential of this pattern. This is the diagram to be implemented:

![Class diagram of the basic structure of the factory-method pattern.](https://cdn-images-1.medium.com/max/2376/1*UmbP1kG7sTmBs5PsTC2jCw.jpeg)

First of all, we are going to define the interface (`Product`) of our problem. As it is an interface, all the methods that must be implemented in all the specific products (`ConcreteProduct1` and `ConcreteProduct2`) are defined. Therefore, the `Product` interface in our problem is quite simple, as shown below:

```javascript
export interface Product {
  operation(): string;
}
```

The objects that we want to build in our problem must implement the previously defined interface. Therefore, concrete classes `ConcreteProduct1` and `ConcreteProduct2` are created which satisfy the `Product` interface and implement the `operation` method.

```javascript
import { Product } from "./product.interface";

export class ConcreteProduct1 implements Product {
  public operation(): string {
    return "ConcreteProduct1: Operation";
  }
}
```

```javascript
import { Product } from "./product.interface";

export class ConcreteProduct2 implements Product {
  public operation(): string {
    return "ConcreteProduct2: Operation";
  }
}
```


The next step is to define the `Creator` abstract class in which an abstract `factoryMethod` must be defined, which is the one that will be delegated to the concrete classes for the creation of an instance of a concrete object. The really important thing is that it must return an object of the `Product` class.

On the other hand, the operation method has been defined which makes use of the `factoryMethod` abstract method. The `factoryMethod` method that is executed will be that of the concrete class in which it is defined.

```javascript
import { Product } from "./product.interface";

export abstract class Creator {
  protected abstract factoryMethod(): Product;

  public operation(): string {
    const product = this.factoryMethod();
    return `Creator: ${product.operation()}`;
  }
}
```

The classes responsible for creating concrete objects are called `ConcreteCreator`. Each of the `ConcreteCreator` classes implement the `factoryMethod` method in which a new object of the `ConcreteProduct1` or `ConcreteProduct2` class is created depending on the `creator` class that has been used.

```javascript
import { ConcreteProduct1 } from "./concrete-product1";
import { Creator } from "./creator";
import { Product } from "./product.interface";

export class ConcreteCreator1 extends Creator {
  protected factoryMethod(): Product {
    return new ConcreteProduct1();
  }
}
```

```javascript
import { ConcreteProduct2 } from "./concrete-product2";
import { Creator } from "./creator";
import { Product } from "./product.interface";

export class ConcreteCreator2 extends Creator {
  protected factoryMethod(): Product {
    return new ConcreteProduct2();
  }
}
```

Finally, we would see how the class `Client` or `Context` can select which objects created without prior knowledge, and how this pattern keeps the *Open-Closed Principle* (OCP).

```javascript
import { ConcreteCreator1 } from "./concrete-creator1";
import { ConcreteCreator2 } from "./concrete-creator2";
import { Creator } from "./creator";

function client(creator: Creator) {
  console.log(`Client: I'm not aware of the creator's class`);
  console.log(creator.operation());
}

const concreteCreator1 = new ConcreteCreator1();
const concreteCreator2 = new ConcreteCreator2();

client(concreteCreator1);

console.log("----------");

client(concreteCreator2);
```

# Example 2 - POS of a Restaurant (Simple-Factory)

In this example, a solution will be developed that does not satisfy the *Factory-Method pattern* but uses a *FactoryManager* class that is responsible for building any object. This solution breaks with the *Open-Closed Principle*, in addition to having *spaghetti code* in the creation of objects. The interesting thing is that this same example is refactored into the following example using the *factory-method pattern*.

The solution proposed here is not a design pattern, but it is a solution that is widely used in the industry. In fact, it has been called *Simple Factory* and has serious problems as the application scales.

The application to be built is a simple application that allows you to create different types of objects: `Pizza`, `Burger` or `Kebab`.

The creation of these objects is not known a priori and depends on user interaction. The `ProductManager` class is in charge of building an object of a certain class through the `createProduct` method.

Below is the UML diagram of this first proposal. A priori the two problems of this solution are already observed:


1. High coupling of the `ProductManager` class with the system.

2. *Spaghetti code* in the `createProduct` method of the `ProductManager` class which is built with a `switch-case` that breaks the *Open-Closed Principle* when you want to extend to other types of products.

![Simple Factory.](https://cdn-images-1.medium.com/max/2000/1*oTqlvo3bT4cisBlH1QZkYw.jpeg)

As in other examples, we will gradually show the code for the implementation of this solution. The *Product* interface is exactly the same as the one used in the solution proposed by the *Factory-Method pattern*.

```javascript
export interface Product {
  operation(): string;
}
```


The next step consists of the implementation of each of the specific objects that you want to create in this problem: `Burger`, `Kebab` and `Pizza`.

```javascript
import { Product } from "./product.interface";

export class Burger implements Product {
  public operation(): string {
    return "Burger: Results";
  }
}
```

```javascript
import { Product } from "./product.interface";

export class Kebab implements Product {
    public operation(): string {
        return 'Kebab: Operation';
    }
}
```

```javascript
import { Product } from "./product.interface";

export class Pizza implements Product {
    public operation(): string {
        return 'Pizza: Operation';
    }
}
```

Finally, we implement the `ProductManager` class, which is responsible for creating each of the object types based on the type parameter. An enum type has been used that allows us to avoid using strings in the use of the `switch-case` statement.

```javascript
import { Burger } from "./burger.model";
import { Kebab } from "./kebab.model";
import { PRODUCT_TYPE } from "./product-type.enum";
import { Pizza } from "./pizza.model";

export class ProductManager {
  constructor() {}
  createProduct(type): Product {
    switch (type) {
      case PRODUCT_TYPE.PIZZA:
        return new Pizza();
      case PRODUCT_TYPE.KEBAB:
        return new Kebab();
      case PRODUCT_TYPE.BURGER:
        return new Burger();
      default:
        throw new Error("Error: Product invalid!");
    }
  }
}
```

Finally, it would be necessary to show the `Client` or `Context` class that makes use of the `productManager` class. Apparently from the `Client` class it is not observed that under this class there is a strongly coupled code that violates the principles of clean code.

```javascript
import { PRODUCT_TYPE } from "./product-type.enum";
import { ProductManager } from "./product-manager";

const productManager = new ProductManager();

const burger = productManager.createProduct(PRODUCT_TYPE.BURGER);
const pizza = productManager.createProduct(PRODUCT_TYPE.PIZZA);
const kebab = productManager.createProduct(PRODUCT_TYPE.KEBAB);

console.log(burger.operation());
console.log(pizza.operation());
console.log(kebab.operation());
```

# Example 3 - POS of a Restaurant using Factory-Method

In this example, we are going to take up the problem posed in Example 2 (POS of a restaurant) to propose the solution using the *factory-method pattern*. The objective of this solution is to avoid the *spaghetti code* that has been generated in the `productManager` class and to allow respecting the *Open-Closed Principle*.

Therefore, following the same methodology as the one we have presented in the previous examples, we are going to start by looking at the UML diagram that will help us identify each of the parts of this pattern.

![Factoy-Method](https://cdn-images-1.medium.com/max/2000/1*AxszharDjB21rflYcUcPdQ.jpeg)

In this case, the objects that we want to build would be those corresponding to the `Pizza`, `Burger` and `Kebab` classes. These classes implement the `Product` interface. All this part of code is identical to the one presented in the previous example. However, let's review the code to keep it in mind:

```javascript
export interface Product {
   operation(): string;
}
```

```javascript
import { Product } from "./product.interface";

export class Burger implements Product {
  public operation(): string {
    return "Burger: Results";
  }
}
```

```javascript
import { Product } from "./product.interface";

export class Kebab implements Product {
    public operation(): string {
        return 'Kebab: Operation';
    }
}
```

```javascript
import { Product } from "./product.interface";

export class Pizza implements Product {
    public operation(): string {
        return 'Pizza: Operation';
    }
}
```

On the other side of the UML diagram, we can find the `creator` classes. Let's start by reviewing the `Creator` class, which is responsible for defining the `factoryMethod` method, which must return an object that implements the `Product` interface. In addition, we will have the `someOperation` method which makes use of the `factoryMethod` abstract method which is developed in each of the concrete creator classes.

```javascript
import { Product } from "./product.interface";

export abstract class Creator {

    public abstract factoryMethod(): Product;

    public someOperation(): string {
        const product = this.factoryMethod();
        return `Creator: The same creator's code has just worked with ${product.operation()}`;
    }
}
```

We would still have to define each of the specific `BurgerCreator`, `KebabCreator` and `PizzaCreator` creator classes that will create each of the specific objects (NOTE: remember that it is not necessary to always create an object, if we had a structure of data from which instances that were cached were retrieved, the pattern would also be implemented).

```javascript
import { Creator } from "./creator";
import { Kebab } from "./kebab.model";
import { Product } from "./product.interface";

export class KebabCreator extends Creator {
    public factoryMethod(): Product {
        return new Kebab();
    }
}
```

```javascript
import { Creator } from "./creator";
import { Pizza } from "./pizza.model";
import { Product } from "./product.interface";

export class PizzaCreator extends Creator {
    public factoryMethod(): Product {
        return new Pizza();
    }
}
```

```javascript
import { Burger } from "./burger.model";
import { Creator } from "./creator";
import { Product } from "./product.interface";

export class BurgerCreator extends Creator {
  public factoryMethod(): Product {
    return new Burger();
  }
}
```


The last step we would have to complete our example would be to apply the pattern that we have developed using it from the `Client` or `Context` class. It is important to note that the `Client` function does not require any knowledge of the `Creator` or the type of object to be created. Allowing to fully delegate responsibility to specific classes.

```javascript
import { BurgerCreator } from "./burger-creator";
import { Creator } from "./creator";
import { KebabCreator } from "./kebab-creator";
import { PizzaCreator } from "./pizza-creator";

function client(creator: Creator) {
    console.log('Client: I\'m not aware of the creator\'s class, but it still works.');
    console.log(creator.someOperation());
}

const pizzaCreator = new PizzaCreator();
const burgerCreator = new BurgerCreator();
const kebabCreator = new KebabCreator();


console.log('App: Launched with the PizzaCreator');
client(pizzaCreator);

console.log('----------');

console.log('App: Launched with the BurgerCreator');
client(burgerCreator);
```

Finally, I have created three `npm scripts` through which the code presented in this article can be executed:

```javascript
npm run example1
npm run example2
npm run example3
```

GitHub Repo: [https://github.com/Caballerog/blog/tree/master/factory-method-pattern](https://github.com/Caballerog/blog/tree/master/factory-method-pattern)

# Conclusion

*Factoy-Method* is a design pattern that allows respecting the *Open-Closed Principle* and delegates the responsibility for creating objects to specific classes using polymorphism. This allows us to have a much cleaner and more scalable code. It mainly solves the problem that arises when it is necessary to create different types of objects that depend on the interaction of a client with the system, and that it is not known a priori which object the client will create.

Finally, the most important thing about this pattern is not the specific implementation of it, but being able to recognize the problem that this pattern can solve, and when it can be applied. The specific implementation is the least of it since that will vary depending on the programming language used.