Builder Pattern w/ Typescript
Tags: typescript, javascript, codequality, cleancode
Published: 2022-11-01 14:44:06

## 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
        })
    }
}
```
_
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
}
```

_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
    }
}

```
_
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()
```

_Resultado:_

```
{
  name: 'Thais Valin',
  age: 19,
  departament: 'Marketing',
  salary: 8888888
}
{
  name: 'Gabriel Valin',
  age: 23,
  departament: 'Engineering',
  salary: 99999999
}
```

## 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