Options Pattern in Golang

96 阅读1分钟

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.