Builder Pattern w/ Typescript
Gabriel Valin
Posted on November 1, 2022
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
Posted on November 1, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.