Builder Design Pattern

What is a builder design pattern?

Builder design pattern allows us to construct complex objects step by step. It produces different types and representations of an object using the same construction process.

Builder is a creational design pattern

Advantages of builder design pattern:

  • Reduces the code used to initialize the object
  • The number of parameters in the constructor reduces and makes it very readable.
  • It separates the construction and representation of an object.
  • It provides better control over the object construction process.
  • Immutable objects can be built without much complex logic in the object-building process.
  • It supports changing the internal representation of objects.

Disadvantages of builder design pattern:

  • It requires writing extra code to implement the builder, more code requires more maintenance.
  • Requires creating a separate ConcreteBuilder for different types of objects.

Example of builder design pattern:

// Client.ts
import {UserBuilder} from "./UserBuilder";
import {User} from "./User";

const userObj: User = new UserBuilder('Joe Smith')
    .setAge(24)
    .setPhone("01911016")
    .setAddress("Munich, Germany")
    .build();
console.log(userObj.getName() + " " + userObj.getAge() + " " + userObj.getPhone() + " " + userObj.getAddress());


// UserBuilder.ts
import { User } from "./User";

export class UserBuilder {
    private name: string;
    private age: number;
    private phone: string;
    private address: string;

    constructor(name: string) {
        this.name = name;
    }

    getName() {
        return this.name;
    }
    setAge(value: number): UserBuilder {
        this.age = value;
        return this;
    }
    getAge() {
        return this.age;
    }
    setPhone(value: string): UserBuilder {
        this.phone = value;
        return this;
    }
    getPhone() {
        return this.phone;
    }
    setAddress(value: string): UserBuilder {
        this.address = value;
        return this;
    }
    getAddress() {
        return this.address;
    }

    build(): User {
        return new User(this);
    }
}


// User.ts
import { UserBuilder } from "./UserBuilder";

export class User {
    private name: string;
    private age: number;
    private phone: string;
    private address: string;

    constructor(builder: UserBuilder) {
        this.name = builder.getName();
        this.age = builder.getAge();
        this.phone = builder.getPhone();
        this.address = builder.getAddress()
    }

    getName() {
        return this.name;
    }
    getAge() {
        return this.age;
    }
    getPhone() {
        return this.phone;
    }
    getAddress() {
        return this.address;
    }
}