Builder pattern in TypeScript
In this article we will cover the fundamentals of the Builder pattern and show case how it can be implemented and used in a project.
What is Builder pattern
The Builder pattern is a design pattern that allows the creation of a complex object to be created with a step-by-step approach to provide a flexible solution.
Read more details of the Builder pattern here
Why Builder pattern?
- Handle classes which takes a lot of arguments in an elegant way
- If a class has a large amount of optional parameters, the Builder approach will be a very handy solution to get rid of unnecessary noice and be less error prone.
Example in code
All right, let dive into the code and see how we can implement a class which are using the Builder pattern in TypeScript.
Let's create a new class called Car
with some mandatory and optional parameters
export class Car { // Required params brand: string; model: string; // Optional params horsePower!: number; rangeInKm!: number; kwh!: number; constructor(builder: CarBuilder) { this.brand = builder.brand; this.model = builder.model; this.horsePower = builder.horsePower; this.kwh = builder.kwh; this.rangeInKm = builder.rangeInKm; } }
And now lets create our Builder. Note that we are returning this
in all the setters, this enables us to do the chaining
when we are creating the object.
export class CarBuilder { // Required params brand: string; model: string; // Optional params horsePower!: number; rangeInKm!: number; kwh!: number; constructor(brand: string, model: string) { this.brand = brand; this.model = model; } public setHorsePower(horsePower: number) { this.horsePower = horsePower; return this; } public setRangeInKm(rangeInKm: number) { this.rangeInKm = rangeInKm; return this; } public setKwh(kwh: number) { this.kwh = kwh; return this; } public build(): Car { return new Car(this); } }
All right, that's it. Now lets do some creation of objects.
const car: Car = new CarBuilder("Tesla", "Model S") .setHorsePower(200) .setKwh(100) .setRangeInKm(600) .build(); const carWithoutRange: Car = new CarBuilder("Volvo", "XC40") .setHorsePower(200) .setKwh(100) .build();
Cool. There we got two objects, one with all parameters and one that are skipping the range. If this would be done in a traditional
way we would need to initialize like this for example:
const car = new Car('Volvo', 'XC40', null, 200, 100);
Of course, it is not the end of the world, but in more complex scenarious it's not that pretty throwing null and undefined values around in the code.
Summary
In todays post, we explored the Builder pattern and implemented it in TypeScript with an example class called Car
and initialized it using the Builder pattern with the chaning approach.
To dig down even more into the pattern there are excellent articles that can be found, I will link to some of them below. Hope you found this useful, and thanks for reading. Cheers!