go的option模式
1.函数option
把option定义为函数。
go
package main
import "fmt"
// ServerConfig 定义服务器配置
type ServerConfig struct {
Port int
Timeout int
}
// Option 定义函数选项类型
type Option func(*ServerConfig)
// WithPort 设置服务器端口
// 这是一个闭包函数
func WithPort(port int) Option {
return func(cfg *ServerConfig) {
cfg.Port = port
}
}
// WithTimeout 设置超时时间
func WithTimeout(timeout int) Option {
return func(cfg *ServerConfig) {
cfg.Timeout = timeout
}
}
// NewServer 创建一个新的服务器实例
// options将参数一并传入
func NewServer(options ...Option) *ServerConfig {
cfg := &ServerConfig{
Port: 8080,
Timeout: 30,
}
for _, opt := range options {
opt(cfg)
}
return cfg
}
func main() {
// 创建服务器实例并指定选项
server := NewServer(
WithPort(9090),
WithTimeout(60),
)
fmt.Printf("Server Port: %d, Timeout: %d\n", server.Port, server.Timeout)
}
NewServer
函数用于创建一个新的 ServerConfig
实例。它接受一个或多个 Option
类型的参数,并使用这些参数来配置 ServerConfig
的实例。
option使用场景:
对象配置:当需要创建一个对象,并且这个对象有很多可配置的属性时,使用Option模式可以避免构造函数的参数列表变得冗长和难以管理。
go
func main() {
c := &ServerConfig{
Port: 9090,
Timeout: 30,
}
// x记住了80
x := WithPort(80)
// x函数传入参数c,x函数里面能访问80
x(c)
}
闭包的好处:
- 封装状态和行为:闭包可以封装函数及其相关的引用环境,将数据和行为捆绑在一起,形成一个独立的单元。这使得函数不仅仅是一个独立的执行单元,还能够保持其自己的状态,从而在后续的调用中能够持续地使用或修改这些状态。
2.接口option
把option定义为接口。
go
package main
import "fmt"
type ServerConfig struct {
Port int
Timeout int
}
type ServerOption interface {
Apply(config *ServerConfig)
}
type Port struct {
Value int
}
func (p Port) Apply(config *ServerConfig) {
config.Port = p.Value
}
type Timeout struct {
Value int
}
func (t Timeout) Apply(config *ServerConfig) {
config.Timeout = t.Value
}
func NewServerConfig(options ...ServerOption) *ServerConfig {
s := new(ServerConfig)
for _, opt := range options {
opt.Apply(s)
}
return s
}
func main() {
p := Port{8080}
t := Timeout{10}
s := NewServerConfig(p, t)
fmt.Println(s)
}