Functional options — паттерн конфигурации объектов через функции. Вместо структуры конфига или десятка параметров в конструкторе передаёшь функции-опции.
type Server struct {
port int
timeout time.Duration
logger *slog.Logger
}
type Option func(*Server)
func WithPort(p int) Option {
return func(s *Server) { s.port = p }
}
func WithTimeout(t time.Duration) Option {
return func(s *Server) { s.timeout = t }
}
func NewServer(opts ...Option) *Server {
s := &Server{port: 8080, timeout: 30 * time.Second}
for _, opt := range opts {
opt(s)
}
return s
}
// использование:
srv := NewServer(WithPort(9090), WithTimeout(time.Minute))
Плюсы: дефолты из коробки, легко добавлять опции без ломки API, самодокументирующийся код. Минусы: чуть больше бойлерплейта. Этот паттерн используется в куче Go-библиотек — gRPC, Zap, go-kit.