Go 中常见的几种对象构造模式

以下是 Go 中常见的几种对象构造模式,每种都有使用场景和优缺点。

一、基础构造方式(直接初始化)

适用场景:结构体较简单,初始化不需要校验逻辑。

1
2
3
4
5
6
7
8
9
type User struct {
	Name string
	Age  int
}

func main() {
	var user = User{Name: "黎童鞋", Age: 25}
	fmt.Println(user)
}

二、工厂函数模式

适用场景:需要封装初始化逻辑,如默认值、校验、依赖注入等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type User struct {
	Name string
	Age  int
}

func NewUser(name string, age int) *User {
	if age < 0 {
		age = 0
	}
	return &User{
		Name: name,
		Age:  age,
	}
}

func main() {
	user := NewUser("黎童鞋", -10)
	fmt.Println(user)
}

三、构建者模式(Builder Pattern)

适用场景:结构体字段很多,且需要灵活地设置部分字段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
type User struct {
	Name string
	Age  int
	City string
}

type UserBuilder struct {
	user User
}

func NewUserBuilder() *UserBuilder {
	return &UserBuilder{user: User{}}
}

func (b *UserBuilder) SetName(name string) *UserBuilder {
	b.user.Name = name
	return b
}

func (b *UserBuilder) SetAge(age int) *UserBuilder {
	b.user.Age = age
	return b
}

func (b *UserBuilder) SetCity(city string) *UserBuilder {
	b.user.City = city
	return b
}

func (b *UserBuilder) Build() User {
	return b.user
}

func main() {
	user := NewUserBuilder().
		SetName("黎童鞋").
		SetAge(25).
		SetCity("深圳").
		Build()
	fmt.Println(user)
}

四、选项函数模式(Functional Options Pattern)

适用场景:参数过多或需要动态配置参数的情况,常见于中间件、库等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
type User struct {
	Name string
	Age  int
	City string
}

type Option func(*User)

func WithName(name string) Option {
	return func(u *User) {
		u.Name = name
	}
}

func WithAge(age int) Option {
	return func(u *User) {
		u.Age = age
	}
}

func WithCity(city string) Option {
	return func(u *User) {
		u.City = city
	}
}

func NewUser(opts ...Option) *User {
	user := &User{}
	for _, opt := range opts {
		opt(user)
	}
	return user
}

func main() {
	user := NewUser(
		WithName("黎童鞋"),
		WithAge(25),
		WithCity("深圳"),
	)
	fmt.Println(user)
}

五、使用 init() 函数或全局变量初始化(不推荐用于复杂对象)

适用场景:简单默认对象、不需要参数初始化

1
2
3
4
5
var defaultUser User

func init() {
	defaultUser = User{Name: "默认用户", Age: 0}
}

总结对比

模式类型 优点 缺点 适用场景
直接初始化 简洁直观 不可封装逻辑 简单对象
工厂函数 封装逻辑 略繁琐 需要默认值/校验
构建者模式 可读性强、灵活 代码多 字段多、组合复杂
选项函数 最灵活、可扩展 难调试 中间件/API
init() 或全局 简单快速 不适合复杂逻辑 静态配置对象
本文作者:
本文链接: https://hgnulb.github.io/blog/2025/22386250
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!