What It Is
The Builder pattern constructs a complex object step by step. Instead of one constructor with a long, confusing argument list, the builder offers small named steps — and a final Build() that returns the finished object.
In Go the steps usually return the builder itself, so calls chain into a readable sentence.
Example: Building a Pizza
Compare NewPizzaBuilder("large").Cheese().Topping("mushrooms") with a constructor like NewPizza("large", true, []string{...}) — the builder says what every value means, and optional parts are simply skipped.
Steps that chain
Every step is named and optional: the small pizza skips them all. No true, nil, false argument soup.
Output: Go program and captured output
package main
import "fmt"
type Pizza struct {
size string
cheese bool
toppings []string
}
type PizzaBuilder struct {
pizza Pizza
}
func NewPizzaBuilder(size string) *PizzaBuilder {
return &PizzaBuilder{pizza: Pizza{size: size}}
}
func (b *PizzaBuilder) Cheese() *PizzaBuilder {
b.pizza.cheese = true
return b
}
func (b *PizzaBuilder) Topping(t string) *PizzaBuilder {
b.pizza.toppings = append(b.pizza.toppings, t)
return b
}
func (b *PizzaBuilder) Build() Pizza {
return b.pizza
}
func main() {
big := NewPizzaBuilder("large").
Cheese().
Topping("mushrooms").
Topping("olives").
Build()
small := NewPizzaBuilder("small").Build()
fmt.Printf("%s pizza, cheese: %v, toppings: %v\n", big.size, big.cheese, big.toppings)
fmt.Printf("%s pizza, cheese: %v, toppings: %v\n", small.size, small.cheese, small.toppings)
}
When to Use It
Use it when an object has many optional parts, or when construction has real steps that deserve names. Requests, queries, and configurations are classic builder territory.
Skip it for simple structs — Go's struct literal Pizza{size: "large"} with named fields is already a fine little builder for the easy cases.
Pros and Cons
Pros: readable construction; optional parts without giant argument lists; the object can be validated once, in Build().
Cons: a second type to write and maintain; overkill where a struct literal already reads well.