What It Is
The State pattern gives an object different behavior in different states by making each state its own type. The object holds its current state and delegates to it; moving to another state means swapping the value.
It replaces the growing switch status { ... } repeated through half the methods with one small type per state.
Example: An Order's Life
An order is new, then paid, then shipped. Each state type answers Describe() its own way and knows which state comes next — the order itself contains no status logic at all.
Each state is a type
Advance() is one line forever. Adding a "delivered" state is a new type plus one changed Next() — no switch to hunt through.
Output: Go program and captured output
package main
import "fmt"
type State interface {
Next() State
Describe() string
}
type New struct{}
func (New) Next() State { return Paid{} }
func (New) Describe() string { return "new - waiting for payment" }
type Paid struct{}
func (Paid) Next() State { return Shipped{} }
func (Paid) Describe() string { return "paid - packing the box" }
type Shipped struct{}
func (Shipped) Next() State { return Shipped{} }
func (Shipped) Describe() string { return "shipped - on its way" }
type Order struct {
state State
}
func (o *Order) Advance() {
o.state = o.state.Next()
}
func main() {
o := &Order{state: New{}}
fmt.Println(o.state.Describe())
o.Advance()
fmt.Println(o.state.Describe())
o.Advance()
fmt.Println(o.state.Describe())
}
When to Use It
Use it when an object's behavior genuinely differs by state and the states have real rules about transitions — orders, documents (draft/review/published), connections, game characters.
Skip it when a status is only displayed, never changes behavior. A string field and one switch is fine below three states with simple rules.
Pros and Cons
Pros: each state's rules live in one small type; impossible transitions are simply not written; new states extend instead of modifying.
Cons: many tiny types for simple machines; the flow of the whole machine is spread across files — a diagram in a comment helps.