DEV Community

Cover image for Builder Pattern w/ Typescript
Gabriel Valin
Gabriel Valin

Posted on

Builder Pattern w/ Typescript

Ideia

A ideia inicial do Builder Pattern é possibilidade de criar objetos complexos com a maior variação de configurações possíveis, uma alternativa ao pattern Factory Method.

Contexto

Temos diversos departamentos em nossa empresa e vamos criar usuários e distribuí-los nos mesmos.

Como podemos via códificação, criar uma maneira de centralizar essa criação e passar as devidas configurações para diversos usuários? Builder!!!

Criando tipos e nossa class User.

export type UserInfo = {
    name: string
    age: number
    departament: string
    salary: number
}

export class User {
    name = ''
    age = 0
    departament = ''
    salary = 0

    create() {
        console.log({
            name: this.name,
            age: this.age,
            departament: this.departament,
            salary: this.salary
        })
    }
}
Enter fullscreen mode Exit fullscreen mode

_
Criando o protocolo que a classe concreta do Builder deverá implementar._


import { User } from ".."

export interface UserBuilder {
    setName(name: string): this
    setAge(age: number): this
    setDepartament(departament: string): this
    setSalary(salary: number): this
    getUser(): User
}
Enter fullscreen mode Exit fullscreen mode

Criando nossa classe concreta de UserBuilder.

import { User } from ".."
import { UserBuilder } from "../protocols/user-builder-protocol"

export class ConcreteUserBuilder implements UserBuilder {
    user: User

    constructor() {
        this.user = new User()
    }

    setName(name: string): this {
        this.user.name =  name
        return this
    }

    setAge(age: number): this {
        this.user.age =  age
        return this
    }

    setDepartament(departament: string): this {
        this.user.departament =  departament
        return this
    }

    setSalary(salary: number): this {
        this.user.salary =  salary
        return this
    }

    getUser(): User {
        return this.user
    }
}

Enter fullscreen mode Exit fullscreen mode

_
Implementando a criação de novos usuários._


import { ConcreteUserBuilder } from "../builder/user-builder"

class EngineerUser {
    static buildUser() {
        return new ConcreteUserBuilder()
            .setName('Gabriel Valin')
            .setAge(23)
            .setDepartament('Engineering')
            .setSalary(99999999) //hahahaha :D
            .getUser() 
    }
}

class MarketingUser {
    static buildUser() {
        return new ConcreteUserBuilder()
            .setName('Thais Valin')
            .setAge(19)
            .setDepartament('Marketing')
            .setSalary(8888888) //hahahaha :D
            .getUser() 
    }
}

const newEngineer = EngineerUser.buildUser()
const newMarketing = MarketingUser.buildUser()

newMarketing.create()
newEngineer.create()
Enter fullscreen mode Exit fullscreen mode

Resultado:

{
  name: 'Thais Valin',
  age: 19,
  departament: 'Marketing',
  salary: 8888888
}
{
  name: 'Gabriel Valin',
  age: 23,
  departament: 'Engineering',
  salary: 99999999
}
Enter fullscreen mode Exit fullscreen mode

Conclusão

Está foi uma maneira simplificada de mostrar como utilizar o pattern Builder.

Uma maneira legal de se pensar para entender esse pattern é imaginar a construção de uma casa, onde definimos numa classe principal (User) que ela terá algumas propriedades (janelas, portas, quantidade de banheiros, quartos, etc..), após isso devemos falar para a construtora que a casa deverá ser construída mantendo o padrão de construção que foi passado (interface UserBuilder), por final, a construtora irá criar e separar para os funcionários as funções de construção que ao final vão gerar uma casa pronta (ConcreteUserBuilder).

Com isso é possível que a construtora sempre crie casas complexas podendo definir suas propriedades sem muita dificuldade. (EngineerUser, MarketingUser). :D

Links para se aprofundar: https://refactoring.guru/design-patterns/builder/typescript/example

Top comments (0)