Option模式:
把可选参数封装成函数,通过可变参数传入构造函数,在初始化对象时应用。
//配置结构体
type Client struct {
Addr string
Port int
Timeout time.Duration
MaxConn int
TLS bool
}
// Option 定义配置选项函数类型
type Option func(*Client)
// NewClient 创建Client实例,接受可变参数的配置选项
func NewClient(addr string, port int, opts ...Option) *Client {
c := &Client{
Addr: addr,
Port: port,
Timeout: 30 * time.Second,
MaxConn: 100,
TLS: false,
}
for _, opt := range opts {
opt(c)
}
return c
}
// 配置选项函数
func WithTimeout(timeout time.Duration) Option { returnfunc(c *Client) { c.Timeout = timeout } }
func WithMaxConn(maxConn int) Option { returnfunc(c *Client) { c.MaxConn = maxConn } }
func WithTLS(tls bool) Option { returnfunc(c *Client) { c.TLS = tls } }调用方式:
// 只使用必填参数
client1 := NewClient("127.0.0.1", 8080)
// 一个可选参数
client2 := NewClient("127.0.0.1", 8080, WithTimeout(60*time.Second))
// 多个可选参数
client3 := NewClient("127.0.0.1", 8080,
WithTimeout(60*time.Second),
WithMaxConn(200),
WithTLS(true),
)优点:
- 代码简洁:每个选项独立函数
- 可读性高:调用时选项名称清楚
- 扩展性强:新增参数只需加一个函数
- 默认值集中管理:所有默认值在 NewClient 中统一定义
进阶:
//参数验证
func WithMaxConn(maxConn int) Option {
if maxConn <= 0 {
panic("maxConn must be positive")
}
return func(c *Client) { c.MaxConn = maxConn }
}//配置选项组合
func WithProductionConfig() Option {
return func(c *Client) {
WithTimeout(60*time.Second)(c)
WithMaxConn(1000)(c)
WithTLS(true)(c)
}
}
// 调用
client := NewClient("api.example.com", 443, WithProductionConfig())//隐藏内部字段,提供接口
type client struct {
addr string
port int
timeout time.Duration
maxConn int
tls bool
}
type Client interface { DoRequest() error }
func newClient(addr string, port int, opts ...Option) Client {
c := &client{addr: addr, port: port, timeout: 30*time.Second, maxConn: 100}
for _, opt := range opts { opt(c) }
return c
}- Option 模式不仅仅是默认值,它还能灵活组合可选参数、做校验、隐藏复杂逻辑。
- 新增字段时,无需修改原有构造函数,符合开闭原则。
Option模式解决了 Go 对象初始化的核心痛点:
- 去除了构造函数的冗余代码
- 提高了代码的可读性和可维护性
- 符合开闭原则:扩展配置项时不修改已有的代码
- 默认值集中管理