Middle
Tell us about the 'Builder' design pattern.
sobes.tech AI
Answer from AI
The "Builder" design pattern is a creational pattern that allows for step-by-step construction of complex objects. It separates the construction process of a complex object from its representation, so that the same construction process can create different representations.
Main components:
- Builder: An interface or abstract class defining methods for creating parts of a complex object.
- Concrete Builder: Implements the Builder interface and provides specific implementations for building parts of the object. It stores intermediate results and provides a method to retrieve the finished object.
- Director: An optional component that defines the order of calling builder methods to create the object. It does not know about the specific builders.
- Product: The complex object that is created by the builder.
Application:
- When the process of creating an object is complex and involves many optional steps.
- When it is necessary to create different representations of the same object using the same construction process.
- When the constructor of the object has many parameters.
Example in Go:
// Product - complex object
type Product struct {
PartA string
PartB string
PartC string
}
// Builder - interface for builder
type Builder interface {
BuildPartA()
BuildPartB()
BuildPartC()
GetProduct() *Product
}
// ConcreteBuilder - specific builder
type ConcreteBuilder struct {
product *Product
}
func NewConcreteBuilder() *ConcreteBuilder {
return &ConcreteBuilder{product: &Product{}}
}
func (cb *ConcreteBuilder) BuildPartA() {
cb.product.PartA = "Part A built"
}
func (cb *ConcreteBuilder) BuildPartB() {
cb.product.PartB = "Part B built"
}
func (cb *ConcreteBuilder) BuildPartC() {
cb.product.PartC = "Part C built"
}
func (cb *ConcreteBuilder) GetProduct() *Product {
return cb.product
}
// Director - optional
type Director struct {
builder Builder
}
func NewDirector(builder Builder) *Director {
return &Director{builder: builder}
}
func (d *Director) Construct() {
d.builder.BuildPartA()
d.builder.BuildPartB()
d.builder.BuildPartC()
}
// Usage
// concreteBuilder := NewConcreteBuilder()
// director := NewDirector(concreteBuilder)
// director.Construct()
// product := concreteBuilder.GetProduct()
// fmt.Printf("Product created: %+v\n", product)
Advantages:
- Isolates the object construction code from its client code.
- Allows changing the internal representation of the product without changing client code.
- Enables step-by-step construction of the object.
- Simplifies creation of objects with many parameters.
Disadvantages:
- Increases the amount of code (classes/interfaces) for object creation.
- May be redundant for simple objects.