Golang Option模式和链式调用
1. Option 模式
1.1 常规模式
type User struct {
Name string
Age int
}
type UserOption func(user *User)
func WithName(name string) UserOption {
fmt.Println("WithName")
return func(user *User) {
user.Name = name
}
}
func WithAge(age int) UserOption {
return func(user *User) {
user.Age = age
}
}
// 默认用户实现
func DefaultUser() *User {
return &User{
Name: uuid.NewString(),
Age: 0,
}
}
func NewUser(options ...UserOption) *User {
// 这里还可以加一个默认user实现,用于用户不进行任何option的
defaultUser := DefaultUser()
// 遍历的时候直接对defaultUser进行修改
user := &User{}
// 遍历函数的时候就已经执行了
for _, option := range options {
// 这个option其实就是WithName和WithAge的返回值
// 也就是UseOption这个函数
// 所以需要参数*User
option(defaultUser )
}
return defaultUser
}
1.2 检索过滤的option模式
type QueryOption interface {
// Apply 用于执行筛选条件
Apply([]*User) []*User
}
// QueryUser 重点
// 把初始用户集合传进来,去过每一个option
func QueryUser(users []*User, options ...QueryOption) []*User {
resultUsers := users
for _, option := range options {
// 这个执行的是实现每个QueryOption接口的Apply方法
// 挨个筛选,where和limit
resultUsers = option.Apply(resultUsers)
}
return resultUsers
}
type Where struct {
Name string
FromAge int
ToAge int
}
func (w Where) Apply(users []*User) []*User {
resultUsers := make([]*User, 0, len(users))
for _, user := range users {
if user.Name == w.Name {
resultUsers = append(resultUsers, user)
}
}
return resultUsers
}
type limit struct {
Offset int
Count int
}
func (l limit) Apply(users []*User) []*User {
if l.Offset >= len(users) {
return nil
}
if l.Offset+l.Count >= len(users) {
return users[l.Offset:]
}
return users[l.Offset : l.Offset+l.Count]
}
func TestNewUser(t *testing.T) {
user := NewUser(WithName("Sakura"), WithAge(11))
user1 := NewUser(WithName("Sakuras"), WithAge(12))
user2 := NewUser(WithName("Sakura"), WithAge(13))
user3 := NewUser(WithName("Sakura"), WithAge(14))
user4 := NewUser(WithName("Sakura"), WithAge(15))
user5 := NewUser(WithName("Sakura"), WithAge(16))
user6 := NewUser(WithName("Sakura"), WithAge(17))
fmt.Println(user)
users := []*User{user, user1, user2, user3, user4, user5, user6}
queryUser := QueryUser(users, &Where{
Name: "Sakura",
}, limit{
Offset: 0,
Count: 3,
})
for _, u := range queryUser {
fmt.Println(*u)
}
}
2. 链式调用
// User 定义User结构体
type User struct {
name string
age int
email string
}
// WithName 添加链式调用方法
func (u *User) WithName(name string) *User {
u.name = name
return u
}
func (u *User) WithAge(age int) *User {
u.age = age
return u
}
func (u *User) WithEmail(email string) *User {
u.email = email
return u
}
// 初始化User的方法
func NewUser() *User {
return &User{}
}
func main() {
// 链式调用创建用户
newUser := NewUser().
WithName("Alice").
WithAge(25).
WithEmail("alice@example.com")
fmt.Printf("New user created: %+v", newUser)
}
评论区