函数选项模式
什么是函数选项模式
在 Go 语言中,函数选项模式是一种优雅的设计模式,用于处理函数的可选参数。它提供了一种灵活的方式,允许用户在函数调用时传递一组可选参数,而不是依赖于固定数量和顺序的参数列表。
哪些地方应用
gRPC,Kubernetes,Kratos,Beego
函数选项模式的实现
函数选项模式的实现一般包含以下几个部分:
- 选项结构体:用于存储函数的配置参数
- 选项函数类型:接收选项结构体参数的函数
- 定义功能函数:接收 0 个或多个固定参数和可变的选项函数参数
- 设置选项的函数:定义多个设置选项的函数,用于设置选项
示例:
原代码
package main
import (
"fmt"
"time"
)
type Server struct {
Addr string
Port string
ReadTimeout time.Duration
WriteTimeout time.Duration
Timeout time.Duration
}
func NewServer(addr string, port string, readTimeout time.Duration, writeTimeout time.Duration, timeout time.Duration) Server {
return Server{
Addr: addr,
Port: port,
ReadTimeout: readTimeout,
WriteTimeout: writeTimeout,
Timeout: timeout,
}
}
func main() {
server := NewServer("localhost", ":8080", 2*time.Second, 2*time.Second, 4*time.Second)
fmt.Println(server)
}
缺点:
- 结构体属性多,参数列表太长,调用者负担大,容易写错
- 没有默认值,默认是零值
函数选项模式:
package main
import (
"fmt"
"time"
)
type Server struct {
Addr string
Port string
ReadTimeout time.Duration
WriteTimeout time.Duration
Timeout time.Duration
}
type Option func(*Server)
func WithAddr(addr string) Option {
return func(s *Server) {
s.Addr = addr
}
}
func WithPort(port string) Option {
return func(s *Server) {
s.Port = port
}
}
func WithReadTimeout(readTimeout time.Duration) Option {
return func(s *Server) {
s.ReadTimeout = readTimeout
}
}
func WithWriteTimeout(writeTimeout time.Duration) Option {
return func(s *Server) {
s.WriteTimeout = writeTimeout
}
}
func WithTimeout(timeout time.Duration) Option {
return func(s *Server) {
s.Timeout = timeout
}
}
func NewServer(options ...Option) *Server {
srv := &Server{
Addr: "localhost",
Port: ":8080",
ReadTimeout: 2 * time.Second,
WriteTimeout: 2 * time.Second,
Timeout: 4 * time.Second,
}
for _, option := range options {
option(srv)
}
return srv
}
func main() {
server := NewServer(WithPort(":9000"))
fmt.Println(server)
}
函数选项模式的好处
- 易于使用:调用者可以选择性的设置函数参数,而不需要记住参数的顺序和类型;
- 可读性强:函数选项模式的代码有着自文档化的特点,调用者能够直观地理解代码的功能;
- 扩展性好:通过添加新的
Option
参数选项,函数可以方便地扩展功能,无需修改函数的签名; - 函数选项模式可以提供默认参数值,以减少参数传递的复杂性。
函数选项模式的缺点
前面提到了函数选项模式的优势(好处),但也必须承认它存在一些缺点。
- 复杂性:函数选项模式引入了更多的类型和概念,需要更多的代码和逻辑来处理。这增加了代码的复杂性和理解的难度,尤其是对于初学者来说。
- 可能存在错误的选项组合:由于函数选项模式允许在函数调用中指定多个选项,某些选项之间可能存在冲突或不兼容的情况。这可能导致意外的行为或错误的结果。
- 不适用于所有情况:函数选项模式适用于有大量可选参数或者可配置选项的函数,但对于只有几个简单参数的函数,使用该模式可能过于复杂和冗余。在这种情况下,简单的命名参数可能更直观和易于使用。
推荐阅读
Go语言设计模式之函数选项模式 | 李文周的博客