Functional Options 今天我来讲一下在go语言编程中一种很常用的编程模式 - Functional Options 模式。Functional Options 模式是目前在Go语言中最流行的一种编程模式, 在 Kubernetes 等开源项目中就有 Functional Options 的影子。接下来我们就来聊一聊 Functional Options 和它解决的问题。
常见的使用场景 在我们编程中,我们会经常性的需要对一个对象进行相关的配置。比如下面这个结构实体:
type Server struct { Addr string Port int Protocol string TLS *tls.Config } 在这个 Server 对象中,我们可以看到: 有侦听的IP地址 Addr 和端口号 Port ,这两个配置选项是必填的。 然后,还有协议 Protoco 字段,这几个字段是不能为空的,但是有默认值的,例如协议的默认值是tcp。 还有一个 TLS 这个是 HTTPS 安全链接,需要配置相关的证书和私钥。这个是可以为空的, 为空就是不使用 HTTPS。
所以根据上述结构体的描述,我们需要有多种不同的创建不同配置 Server 的函数签名,如下所示:
func NewDefaultServer(addr string, port int) (*Server, error) { return &Server{addr, port, "tcp", nil}, nil } func NewTLSServerWithMaxConnAndTimeout(addr string, port int, tls *tls.Config) (*Server, error) { return &Server{addr, port, "tcp", tls}, nil } 因为go语言与Python等语言是不同的,没用重载函数,所你得用不同的函数名来应对不同的配置选项。
新增配置对象 要解决这个问题,最常见的方式是使用一个配置对象,如下所示:
type Config struct { Protocol string TLS *tls.Config } type Server struct { Addr string Port int Conf *Config } 我们将那些不是必填的字段存入新的结构体中,于是Server结构体就变成如上图所示的样子。 于是,我们只需要一个 NewServer() 的函数了,在使用前需要构造 Config 对象。
...