Go的Option模式

By kcersing , 12 二月, 2026

 

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 对象初始化的核心痛点:

  1. 去除了构造函数的冗余代码
  2. 提高了代码的可读性和可维护性
  3. 符合开闭原则:扩展配置项时不修改已有的代码
  4. 默认值集中管理

 

 

 

 

 

 

 

标签