选项模式
简介
选项模式(Functional Options Pattern)是 Go 语言中一种构造复杂对象的设计模式,解决传统构造函数在面对大量可选参数时参数膨胀和可读性差的问题。
常见使用对象
- 复杂对象的初始化:如数据库连接、HTTP服务、日志组件等需要多个参数配置的场景
- 可选参数多:当对象包含超过3个可选参数时,选项模式显著提升代码可读性
优点
- 代码简洁:避免构造函数参数膨胀。
- 可读性强:通过命名函数明确参数作用(如
WithTLS()
比true
更直观)。 - 扩展灵活:新增配置项不影响现有代码。
- 默认值支持:自动填充未显式设置的参数。
- 链式调用:支持流畅的配置语法(如
NewServer(WithPort(8080), WithTimeout(10*time.Second))
)。
缺点
- 额外抽象层:需定义选项函数和结构体,简单场景可能过度设计。
示例代码
package options
import "time"
type Server struct {
host string
port int
timeout time.Duration
maxConns int
tls bool
}
type Option func(*Server)
// 设置主机名
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 WithTimeout(timeout time.Duration) Option {
return func(s *Server) {
s.timeout = timeout
}
}
// 设置最大连接数
func WithMaxConns(maxConns int) Option {
return func(s *Server) {
s.maxConns = maxConns
}
}
// 设置是否启用HTTPS
func WithTLS() Option {
return func(s *Server) {
s.tls = true
}
}
func NewServer(opts ...Option) *Server {
// 设置默认值
server := &Server{
host: "localhost",
port: 8080,
timeout: 10 * time.Second,
maxConns: 100,
tls: false,
}
// 应用所有选项函数
for _, opt := range opts {
opt(server)
}
return server
}
client
package options
import (
"testing"
"time"
)
func TestOptions(t *testing.T) {
defaultServer := NewServer()
t.Logf("Default server: %+v", defaultServer)
customServer := NewServer(
WithHost("example.com"),
WithPort(8081),
WithMaxConns(500),
WithTimeout(30*time.Second),
WithTLS(),
)
t.Logf("Custom server: %+v", customServer)
}