Builder Design Pattern

O padrão de design Builder é utilizado para construir objetos complexos de forma incremental, permitindo a criação de diferentes representações de um objeto utilizando o mesmo processo de construção. Neste artigo, vamos explorar como implementar o padr…


This content originally appeared on DEV Community and was authored by Rafael Pazini

O padrão de design Builder é utilizado para construir objetos complexos de forma incremental, permitindo a criação de diferentes representações de um objeto utilizando o mesmo processo de construção. Neste artigo, vamos explorar como implementar o padrão Builder em Golang, entender seus benefícios e analisar um exemplo prático de uso.

O que é o Builder?

O padrão Builder separa a construção de um objeto complexo da sua representação, permitindo que o mesmo processo de construção possa criar diferentes representações. Isso é especialmente útil quando um objeto precisa ser criado em várias etapas ou com várias configurações possíveis.

Benefícios do Builder

  • Separação de Construção e Representação: Permite que a construção de um objeto seja separada da sua representação final.
  • Construção Incremental: Permite a construção de objetos complexos de maneira incremental e passo a passo.
  • Reutilização de Código: Facilita a reutilização de código ao definir passos de construção comuns que podem ser combinados de várias maneiras.

Implementando um Builder

Para implementar nosso Builder, vamos imaginar um objeto complexo onde será necessário inicializar vários campos e até outros objetos agrupados. Que tal uma Casa? Onde teremos dois tipos de construção, uma convencional onde será usado concreto e tijolos, e uma segunda de madeira.

1 - Definindo a Estrutura

Primeiro, precisamos definir a estrutura do objeto que queremos construir. Como dito antes, vamos construir uma casa. Dentro dessa Struct colocaremos o que é necessário para criar uma.

// house.go

package main

type House struct {
    Foundation string
    Structure  string
    Roof       string
    Interior   string
}

2 - Definindo a Interface do Builder

Ainda no mesmo arquivo, vamos definir a interface do nosso Builder que especifica os métodos necessários para construir as diferentes partes da House.

//house.go

package main

type House struct {
    Foundation string
    Structure  string
    Roof       string
    Interior   string
}

type HouseBuilder interface {
    SetFoundation()
    SetStructure()
    SetRoof()
    SetInterior()
    GetHouse() House
}

3 - Implementando concretamente o Builder

Vamos criar dois arquivos novos, concreteHouse e woodHouse. Eles serão a implementação de uma classe concreta que siga a interface HouseBuilder.

//concreteHouse.go

package main

type ConcreteHouseBuilder struct {
    house House
}

func (b *ConcreteHouseBuilder) SetFoundation() {
    b.house.Foundation = "Concrete, brick, and stone"
}

func (b *ConcreteHouseBuilder) SetStructure() {
    b.house.Structure = "Wood and brick"
}

func (b *ConcreteHouseBuilder) SetRoof() {
    b.house.Roof = "Concrete and reinforced steel"
}

func (b *ConcreteHouseBuilder) SetInterior() {
    b.house.Interior = "Gypsum board, plywood, and paint"
}

func (b *ConcreteHouseBuilder) GetHouse() House {
    return b.house
}
//woodHouse.go

package main

type WoodHouseBuilder struct {
    house House
}

func (b *WoodHouseBuilder) SetFoundation() {
    b.house.Foundation = "Wooden piles"
}

func (b *WoodHouseBuilder) SetStructure() {
    b.house.Structure = "Wooden frame"
}

func (b *WoodHouseBuilder) SetRoof() {
    b.house.Roof = "Wooden shingles"
}

func (b *WoodHouseBuilder) SetInterior() {
    b.house.Interior = "Wooden panels and paint"
}

func (b *WoodHouseBuilder) GetHouse() House {
    return b.house
}

4 - Definindo o Director

O Director é uma classe que gerencia a construção de um objeto, garantindo que as etapas de construção sejam chamadas na ordem correta. Ele não sabe nada sobre os detalhes das implementações específicas do Builder, apenas chama os métodos do Builder em uma sequência lógica para criar o produto final.

//director.go

package main

type Director struct {
    builder HouseBuilder
}

func (d *Director) Build() {
    d.builder.SetFoundation()
    d.builder.SetStructure()
    d.builder.SetRoof()
    d.builder.SetInterior()
}

func (d *Director) SetBuilder(b HouseBuilder) {
    d.builder = b
}

5 - Utilizando o Builder

Finalmente, vamos utilizar o Director e os Builders concretos para construir diferentes tipos de casas.

//main.go

package main

import (
    "fmt"
)

func main() {
    cb := &builder.ConcreteHouseBuilder{}
    director := builder.Director{Builder: cb}

    director.Build()
    concreteHouse := cb.GetHouse()

    fmt.Println("Concrete House")
    fmt.Println("Foundation:", concreteHouse.Foundation)
    fmt.Println("Structure:", concreteHouse.Structure)
    fmt.Println("Roof:", concreteHouse.Roof)
    fmt.Println("Interior:", concreteHouse.Interior)
    fmt.Println("-------------------------------------------")

    wb := &builder.WoodHouseBuilder{}
    director.SetBuilder(wb)

    director.Build()
    woodHouse := wb.GetHouse()

    fmt.Println("Wood House")
    fmt.Println("Foundation:", woodHouse.Foundation)
    fmt.Println("Structure:", woodHouse.Structure)
    fmt.Println("Roof:", woodHouse.Roof)
    fmt.Println("Interior:", woodHouse.Interior)
}

Resumindo

  1. Struct House: Representa o produto final que estamos construindo.
  2. Interface HouseBuilder: Define os métodos para construir as diferentes partes da casa.
  3. Implementações Concretas (ConcreteHouseBuilder e WoodHouseBuilder): Implementam a interface HouseBuilder e definem as etapas de construção específicas.
  4. Director: Gerencia o processo de construção, garantindo que as etapas sejam chamadas na ordem correta.
  5. Função main: Demonstra o uso do padrão Builder para construir diferentes tipos de casas, chamando o Director para gerenciar o processo e obtendo o produto final.

Conclusão

O padrão Builder é uma ferramenta para construir objetos complexos de maneira incremental e flexível. Em Golang, a implementação deste padrão é direta e eficaz, permitindo a criação de sistemas modulares e fáceis de manter. Com o uso de interfaces e classes concretas, podemos centralizar a lógica de construção e simplificar a evolução do código à medida que novos requisitos surgem.


This content originally appeared on DEV Community and was authored by Rafael Pazini


Print Share Comment Cite Upload Translate Updates
APA

Rafael Pazini | Sciencx (2024-07-04T18:42:09+00:00) Builder Design Pattern. Retrieved from https://www.scien.cx/2024/07/04/builder-design-pattern/

MLA
" » Builder Design Pattern." Rafael Pazini | Sciencx - Thursday July 4, 2024, https://www.scien.cx/2024/07/04/builder-design-pattern/
HARVARD
Rafael Pazini | Sciencx Thursday July 4, 2024 » Builder Design Pattern., viewed ,<https://www.scien.cx/2024/07/04/builder-design-pattern/>
VANCOUVER
Rafael Pazini | Sciencx - » Builder Design Pattern. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/07/04/builder-design-pattern/
CHICAGO
" » Builder Design Pattern." Rafael Pazini | Sciencx - Accessed . https://www.scien.cx/2024/07/04/builder-design-pattern/
IEEE
" » Builder Design Pattern." Rafael Pazini | Sciencx [Online]. Available: https://www.scien.cx/2024/07/04/builder-design-pattern/. [Accessed: ]
rf:citation
» Builder Design Pattern | Rafael Pazini | Sciencx | https://www.scien.cx/2024/07/04/builder-design-pattern/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.