What It Is
The Strategy pattern makes an algorithm swappable: the surrounding code stays the same, and the interchangeable part — how to price, how to sort, how to compress — is plugged in as a value.
This is the pattern Go simplifies the most: since functions are values, a strategy is often just a function type. No interface, no struct — assign a different function and the behavior changes.
Example: Swappable Pricing
Checkout never changes; the pricing rule is a function value in a field. Regular price, Black Friday, member discount — three functions, one shop.
The strategy is a function value
Three checkouts of the same 50 give three totals — only the assigned function differs. This is also how the standard library sorts: you hand it the comparison strategy.
Output: Go program and captured output
package main
import "fmt"
// The strategy is just a function value in Go.
type Pricing func(price float64) float64
func Regular(p float64) float64 { return p }
func BlackFriday(p float64) float64 { return p * 0.7 }
func Member(p float64) float64 { return p - 5 }
type Shop struct {
pricing Pricing
}
func (s Shop) Checkout(price float64) {
fmt.Printf("total: %.2f\n", s.pricing(price))
}
func main() {
shop := Shop{pricing: Regular}
shop.Checkout(50)
shop.pricing = BlackFriday
shop.Checkout(50)
shop.pricing = Member
shop.Checkout(50)
}
When to Use It
Use it whenever an algorithm varies while its surroundings do not: pricing rules, retry policies, sorting orders, validation modes.
Skip it when there is one algorithm and no realistic second. Use the interface form instead of a function only when a strategy needs its own state or several methods.
Pros and Cons
Pros: behavior swaps at run time; each strategy is small and testable alone; in Go it is nearly free — a function type and an assignment.
Cons: the chosen strategy is invisible at the call site — debugging means finding what was assigned; too many micro-strategies fragment simple logic.