How to implement Factory method design pattern using TypeScript?
In this post, I’ll be explain how to implement Factory method design pattern using TypeScript. I’ll cover some other popular design patterns soon. This post is part of the Design Patterns in TypeScript series. If you would like to learn more, please subscribe to my website for new updates.
What is Factory method pattern?
In class-based programming, the factory method pattern 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.
– Wikipedia
In short, factory pattern deals with the instantiation of objects without exposing the instantiation logic. In other words, a Factory is actually a creator of objects which have a common interface.
Example
Let us consider an example that in our application we have different types of person – person living in village and in a city. Depending on the type of person, we would need to create an instance of the type. In future, we may have more such types for which we will need to create instances of particular types manually.
So, let us take a look at the code below:
namespace FactoryMethodPattern {
export interface IPerson {
getName() : String;
}
export class Villager implements IPerson {
getName(): String {
return "Village Person";
}
}
export class CityPerson implements IPerson {
getName(): String {
return "City Person";
}
}
export enum PersonType
{
Rural,
Urban
}
export class PersonFactory {
public static createProduct(type: PersonType) : IPerson {
if (type === PersonType.Rural) {
return new Villager();
} else if (type === PersonType.Urban) {
return new CityPerson();
}
return null;
}
}
}
- On line no. 3, a common interface named `IPerson` has been defined that must be implemented by supported person types like `Village` and `CityPerson` on line no. 7 and 13.
- Next, we also have an enum for the person type named `PersonType` which is self explanatory.
- On line no. 26, we have a class named `PersonFactory` that is responsible to create objects of correct type. It has a `createProduct` static method that takes a `PersonType`and depending on this type, it returns an object. If a matching type is not found, this Factory returns `null` or can also throw an error/exception (not supported or similar).
We now have this Factory class ready to be used to create objects. Let us look at the code below:
/// <reference path="factoryMethod.ts" />
namespace FactoryMethodPattern {
export namespace Demo {
export function show() : void {
var villager: IPerson = PersonFactory.createProduct(PersonType.Rural);
var cityPerson: IPerson = FactoryMethodPattern.PersonFactory.createProduct(PersonType.Urban);
console.log(villager.getName());
console.log(cityPerson.getName());
};
}
}
The above code is quite simple. It just uses PersonFactory and its method named `createProduct` to pass a person type. In return, the factory gives an object depending on that type. Next, we just log the name of the person in the console.
The output looks like this:
Village Person City Person
I hope this post properly explains how to implement Factory method design pattern using TypeScript. Please refer Design Patterns in TypeScript series to learn more about design patterns in TypeScript.
