Bootstrap

浅谈Go语言Optional模式和Builder模式

在Go语言中,Optional模式和Builder模式都是用于对象构建和配置的重要设计模式,但它们各自具有独特的特点和应用场景。但是使用起来也是非常的类似,就好比电动车和摩托车,都能让你不费太多力气的骑行,把你送到目的地,这篇文章我们就来讨论一下这两个模式的本质区别和不同的使用场景。

我们首先声明一个结构体,后面我们就研究使用两种不同方式来创建这个结构体的实例:

type Person struct {
	name    string
	age     int
	address string
}
Optional模式

Optional模式,也称为选项模式或函数选项模式,是一种用于在函数或结构体构造中提供灵活配置选项的设计模式。它允许以清晰、可读的方式为函数或结构体传递一系列的选项,而不是强制使用大量的参数或固定的配置。

实现方式

在Go语言中,Optional模式通常通过函数选项(functional options)来实现。每个选项函数都可以根据需要修改结构体的字段或者配置。这种方法常用于构造函数,允许根据需求定制对象的属性。

先声明一个functional options:

type Option func(*Person)

然后在New函数中允许专递多个Option:

func NewPerson(opts ...Option) *Person {
	p := &Person{}
	for _, opt := range opts {
		opt(p)
	}
	return p
}

然后实现Option:

func WithName(name string) Option {
	return func(person *Person) {
		person.name = name
	}
}

func WithAge(age int) Option {
	return func(person *Person) {
		person.age = age
	}
}

func WithAddress(addr string) Option {
	return func(person *Person) {
		person.address = addr
	}
}

使用:

func main() {
	newPerson := NewPerson(WithName("John Doe"),
		WithAge(30), WithAddress("Beijing"))
	fmt.Printf("Person: %+v\n", newPerson)
}

优点:①提高代码的可读性和灵活性。②避免构造函数参数过多导致的代码混乱。③允许在运行时动态地配置对象。

应用场景

1)数据库连接配置:使用函数选项来设置连接参数,如主机、端口、用户名、密码等。

2)HTTP请求配置:使用函数选项来设置请求头、超时时间、代理等信息。

3)对象构建:使用函数选项来设置对象的属性,如日志级别、缓存配置等。

Builder模式

Builder模式是一种用于构建复杂对象的设计模式。它将对象的构造过程与对象的表示分离,使得同样的构建过程可以创建不同的对象。Builder模式通过定义一个Builder接口,以及该接口的具体实现类来逐步构建对象。

实现方式

定义一个Builder对象,该对象包含创建目标对象各个部分的方法,以及一个返回最终构建对象的方法。

Builder对象和实例化:

type PersonBuilder struct {
	name    string
	age     int
	address string
}

func NewPersonBuilder() *PersonBuilder {
	return &PersonBuilder{}
}

Builder对象的各个方法实现:

func (pb *PersonBuilder) WithName(name string) *PersonBuilder {
	pb.name = name
	return pb
}

func (pb *PersonBuilder) WithAge(age int) *PersonBuilder {
	pb.age = age
	return pb
}

func (pb *PersonBuilder) WithAddress(address string) *PersonBuilder {
	pb.address = address
	return pb
}

Build方法实现:

func (pb *PersonBuilder) Build() *Person {
	return &Person{
		name:    pb.name,
		age:     pb.age,
		address: pb.address,
	}
}

优点:①可以一步一步地构建对象,使得构建过程更加清晰。②允许在构建过程中进行多种配置,提高了对象的灵活性。③使得代码更加模块化,易于维护和扩展。

应用场景

1)构建复杂的配置文件。

2)创建定制化的产品对象。

3)需要逐步构建对象的情况,如构建一台电脑,其中包含多个组件(CPU、GPU、RAM、硬盘等)。

两种设计模式的核心思想

Builder模式的核心思想是将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的对象。它通过将复杂对象分解为多个简单的部分,然后一步一步构建而成。

Builder模式的优点在于封装性好,构建和表示分离。其次是扩展性好,各个具体的建造者相互独立,有利于系统的解耦。客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其他模块产生任何影响,便于控制细节风险。但缺点是如果产品的内部变化复杂,建造者也要同步修改,后期维护成本较大。

Options模式(也称为函数选项模式)允许使用可变构造函数构建复杂结构,该构造函数可以接受零个或多个函数作为参数。这些函数选项用于设置对象的可选

其优点是提供了灵活和可扩展的方式来配置类的实例,无需改变构造函数签名。调用者只需要关注他们关心的选项,忽略其他默认配置,提高了代码的可读性和可维护性。新增选项不需要更改构造函数的签名,对旧代码无影响。适合于有多个配置选项的情况,可以轻松地添加或修改实例的配置,同时保持代码的简洁性。

本质上的不同

关注点:Builder模式关注于将复杂对象的构建过程分解和封装,而Options模式则关注于提供灵活的配置选项来构建对象。

结构复杂度:Builder模式通常涉及多个角色(产品、抽象建造者、具体建造者、指挥者),而Options模式则相对简单,主要包含一个结构体和一些函数选项。

使用场景:Builder模式更适合于需要精确控制对象构建过程和组件的复杂场景,而Options模式则更适合于需要灵活配置多个选项的简单或中等复杂度的对象。

小总结

Optional模式和Builder模式都是Go语言中用于对象构建和配置的重要设计模式。Optional模式通过函数选项提供灵活的配置选项,适用于参数较少且相对简单的情况。而Builder模式则通过逐步构建对象并提供多种配置选项,适用于构建复杂对象的情况。在选择使用哪种模式时,应根据具体需求和对象复杂程度进行权衡。

;