目 录CONTENT

文章目录

Golang Option模式和链式调用

Sakura
2024-03-06 / 4 评论 / 1 点赞 / 35 阅读 / 3393 字 / 正在检测是否收录...

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)
}

1

评论区