Middle
Tell me about the Builder design pattern.
sobes.tech AI
Answer from AI
Builder is a creational pattern that allows constructing complex objects step by step.
It is used when:
- The process of creating an object is complex and involves many steps.
- There is a need to create different representations of the same object.
- The constructor of the object has many optional parameters.
The pattern consists of the following roles:
- Builder: An interface defining the steps to build an object.
- ConcreteBuilder: A specific implementation of Builder that performs the building steps and provides a method to get the finished object.
- Product: The complex object that is being built.
- Director (Optional): Defines the order of calling the building steps.
Example implementation in Golang without Director:
// Product - the object we are building
type Pizza struct {
Dough string
Sauce string
Toppings []string
}
// Builder - the builder interface
type PizzaBuilder interface {
SetDough(dough string) PizzaBuilder
SetSauce(sauce string) PizzaBuilder
AddTopping(topping string) PizzaBuilder
Build() Pizza // Method to get the finished object
}
// ConcreteBuilder - the specific implementation of the builder
type HawaiianPizzaBuilder struct {
pizza Pizza
}
func NewHawaiianPizzaBuilder() *HawaiianPizzaBuilder {
return &HawaiianPizzaBuilder{}
}
func (b *HawaiianPizzaBuilder) SetDough(dough string) PizzaBuilder {
b.pizza.Dough = dough
return b
}
func (b *HawaiianPizzaBuilder) SetSauce(sauce string) PizzaBuilder {
b.pizza.Sauce = sauce
return b
}
func (b *HawaiianPizzaBuilder) AddTopping(topping string) PizzaBuilder {
b.pizza.Toppings = append(b.pizza.Toppings, topping)
return b
}
func (b *HawaiianPizzaBuilder) Build() Pizza {
return b.pizza
}
// Usage example
func main() {
// Create a builder for Hawaiian pizza
builder := NewHawaiianPizzaBuilder()
// Build the pizza step by step
pizza := builder.
SetDough("thin").
SetSauce("tomato").
AddTopping("pineapple").
AddTopping("ham").
Build() // Get the finished pizza
fmt.Printf("Created pizza: %+v\n", pizza)
}
Advantages of the pattern:
- Allows isolating the process of building a complex object from its representation.
- Ensures step-by-step creation of the object.
- Simplifies creating different representations of the same object.
- Makes the code for creating an object more readable and maintainable when there are many parameters.
Disadvantages of the pattern:
- Increases the number of classes in the project.
- Can be redundant for simple objects.