Sometimes we need to initialize an instance according to different arguments, even with different number of arguments, in this case options pattern can be used to make the code cleaner and more maintainable.
For example, we need to new a server instance with timeout or without timeout,
package main
import (
"fmt"
)
type Server struct {
Host string
Port int
Timeout int
}
func (s *Server) Start() {
fmt.Println(s.Host, s.Port, s.Timeout)
}
func New(options ...func(*Server)) *Server {
svr := Server{}
for _, o := range options {
o(&svr)
}
return &svr
}
func WithHost(host string) func(*Server) {
return func(s *Server) {
s.Host = host
}
}
func WithPort(port int) func(*Server) {
return func(s *Server) {
s.Port = port
}
}
func WithTimeout(timeout int) func(*Server) {
return func(s *Server) {
s.Timeout = timeout
}
}
func main() {
s := New(WithHost("localhost"), WithPort(1234), WithTimeout(10))
s.Start()
}
If we do not need the timeout argument, we can remove WithTimeout(10) from the calling of New directly with the flexibility provided by options pattern.