Functional Option Pattern
属于是创建者模型
我们创建实例有很多方法,其本质都是创建结构体
但缺点是,直接去构造结构体代码的可读性并不高,也并不是良好的接口
最常见的方式
type Server struct {
host string
port int
}
func New(host string, port int) *Server {
return &Server{
host: "127.0.0.1",
port: 8080,
}
}
一种简单进阶的方式
这种主要是靠读取配置文件创建实例
type Config struct {
server Server
}
func New2(cfg Server) *Config {
return &Config{cfg}
}
最巨扩展性且可读的方式,函数选项模式
type Option func(*Server)
func New3(options ...Option) *Server {
svr := new(Server)
for _, f := range options {
f(svr)
}
return svr
}
func WithHost(host string) Option {
return func(s *Server) {
s.host = host
}
}
func WithPort(port int) Option {
return func(s *Server) {
s.port = port
}
}
//func main() {
// svr := New3(
// WithPort(8080),
// WithHost("127.0.0.1"),
// )
//}
诚然上面一种写法已经很好了,我们还是有另一种同样的表述方式,更为简洁易扩展
// 同样也是option的方式进行扩展
type Server struct {
host string
port int
timeout time.Duration
}
func NewServer(addr string, options ...func(*Server)) (*Server, error) {
svr := &Server{
host: addr,
}
for _, option := range options {
option(svr)
}
return svr, nil
}
func timeout(d time.Duration) func(*Server) {
return func(server *Server) {
server.timeout = d
}
}
func port(port int) func(*Server) {
return func(server *Server) {
server.port = port
}
}
//func main() {
// server, err := NewServer("127.0.0.1", timeout(1e9), port(8080))
//}