Creational Design Patterns Part 1: Factory Method

Creational Design Patterns Part 1: Factory Method

In this blog article series, we will explore one of the most common creational design patterns: the Factory Method. We will see what it is, why it is useful, and how to implement it in JavaScript with some examples.

What is the Factory Method?

The Factory Method is a 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. It is also known as Virtual Constructor.

The main idea behind this pattern is to encapsulate the object creation logic in a separate method (called the factory method) and delegate it to the subclasses. This way, we can avoid coupling our code with specific classes and have more flexibility and reusability.

Imagine a factory that produces cars. The factory has a production line that consists of several stages, such as the chassis assembly, engine installation, and painting. Each stage of the production line is responsible for a specific task, and each stage relies on the previous stage to produce the car. In this sense, the factory is like a Factory Design Pattern. Each stage of the production line is like a Factory Method that creates a specific part of the car. The chassis assembly stage creates the chassis, the engine installation stage creates the engine, and the painting stage creates the car's final color.

In software development, the Factory Design Pattern is used to create objects in a similar way. The Factory Method is responsible for creating objects, and each Factory Method creates a specific object. For example, imagine a program that creates shapes. The Factory Method would be responsible for creating the shapes, and each Factory Method would create a specific shape, such as a circle or square.

Why use the Factory Method?

The Factory Method can be useful when:

  • We don't know beforehand what type of objects we need to create

  • We want to decouple our code from concrete classes and depend on abstractions

  • We want to delegate the object creation responsibility to subclasses based on some logic or configuration

How to implement the Factory Method in JavaScript?

To implement the Factory Method in JavaScript, we need to define an abstract class (or a base class) that declares an abstract factory method. This method should return an object of a certain type (or an interface). Then, we need to define concrete subclasses that extend the base class and implement the factory method. Each subclass should return a different type of object that conforms to the same interface.

Let's see an example of how we can use the Factory Method pattern to create different types of enemies:

// Define a base Enemy class and some concrete subclasses
class Enemy {
  constructor(name, health, damage) {
    this.name = name;
    this.health = health;
    this.damage = damage;
  }

  attack() {
    console.log(`${this.name} attacks for ${this.damage} damage!`);
  }
}

class Goblin extends Enemy {
  constructor() {
    super('Goblin', 20, 5);
  }
}

class Orc extends Enemy {
  constructor() {
    super('Orc', 30, 10);
  }
}

class Troll extends Enemy {
  constructor() {
    super('Troll', 50, 15);
  }
}

// Define a factory function for creating enemy objects
function createEnemy(type) {
  switch (type) {
    case 'goblin':
      return new Goblin();
    case 'orc':
      return new Orc();
    case 'troll':
      return new Troll();
    default:
      throw new Error(`Invalid enemy type: ${type}`);
  }
}

// Usage example:
const goblin = createEnemy('goblin');
goblin.attack(); // "Goblin attacks for 5 damage!"

const troll = createEnemy('troll');
troll.attack(); // "Troll attacks for 15 damage!"

In this example, the createEnemy factory function takes a type parameter and returns an instance of the appropriate concrete subclass of Enemy based on that type. If an invalid type is passed in, an error is thrown.

This pattern allows you to encapsulate the creation logic for different types of objects in a single place (the factory function) and provides a consistent interface for creating those objects. It also makes it easy to add new types of enemies in the future by simply adding a new subclass of Enemy and updating the createEnemy function to handle that type.

Conclusion

In conclusion, the Factory Design Pattern is a powerful software design pattern that is used to create objects in an efficient, flexible, and easy-to-manage way. Each Factory Method is responsible for creating a specific object or part of an object, and each Factory Method uses a set of rules or algorithms to create the object. By using the Factory Design Pattern, software developers can create software that is scalable, flexible, and easy to maintain.