"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Builder Design Pattern

Builder Design Pattern

Published on 2024-08-31
Browse:156

Builder Design Pattern

The Builder design pattern is used to build complex objects incrementally, allowing the creation of different representations of an object using the same construction process. In this article, we will explore how to implement the Builder pattern in Golang, understand its benefits, and analyze a practical example of use.

What is Builder?

The Builder pattern separates the construction of a complex object from its representation, allowing the same construction process to create different representations. This is especially useful when an object needs to be created in multiple steps or with multiple possible configurations.

Builder Benefits

  • Separation of Construction and Representation: Allows the construction of an object to be separated from its final representation.
  • Incremental Construction: Allows the construction of complex objects incrementally and step by step.
  • Code Reuse: Facilitates code reuse by defining common build steps that can be combined in multiple ways.

Implementing a Builder

To implement our Builder, let's imagine a complex object where it will be necessary to initialize several fields and even other grouped objects. How about a House? Where we will have two types of construction, a conventional one where concrete and bricks will be used, and a second made of wood.

1 - Defining the Structure

First, we need to define the structure of the object we want to build. As said before, we are going to build a house. Inside this Struct we will place what is necessary to create one.

// house.go

package main

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

2 - Defining the Builder Interface

Still in the same file, we will define our Builder interface that specifies the methods needed to build the different parts of the 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 - Concretely implementing the Builder

Let's create two new files, concreteHouse and woodHouse. They will be the implementation of a concrete class that follows the HouseBuilder interface.

//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 - Defining the Director

The Director is a class that manages the construction of an object, ensuring that the construction steps are called in the correct order. It knows nothing about the details of specific Builder implementations, it just calls Builder methods in a logical sequence to create the final product.

//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 - Using the Builder

Finally, we will use the Director and concrete Builders to build different types of houses.

//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)
}

In short

  1. Struct House: Represents the final product we are building.
  2. HouseBuilder Interface: Defines the methods for building the different parts of the house.
  3. Concrete Implementations (ConcreteHouseBuilder and WoodHouseBuilder): Implement the HouseBuilder interface and define specific construction steps.
  4. Director: Manages the construction process, ensuring that the steps are called in the correct order.
  5. Main function: Demonstrates the use of the Builder pattern to build different types of houses, calling the Director to manage the process and obtaining the final product.

Conclusion

The Builder pattern is a tool for building complex objects in an incremental and flexible way. In Golang, the implementation of this pattern is direct and effective, allowing the creation of modular and easy-to-maintain systems. By using concrete interfaces and classes, we can centralize construction logic and simplify code evolution as new requirements emerge.

Release Statement This article is reproduced at: https://dev.to/rflpazini/builder-design-pattern-2hm3?1 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3