Go语言设计模式(四)生成器模式

生成器模式的目标是将复杂对象的构造与其实现分离,以便相同的构造过程可以创建不同的实现.生成器模式主要用于逐步构造一个复杂的对象,并且返回该对象.

1.角色:

1.1生成器:

定义了正确创建产品必须采取的所有步骤的接口.每个步骤通常都是抽象的,因为生成器的实际功能是在具体的类中实现的.

1.2具体生成器:

实现生成器接口的类,具体生成器可以生成任意数量的产品类,这些类具有创建特定复杂产品的功能.

1.3产品:

最终生成的对象.由不同具体生成器创建的产品是独立的,产品之间不受影响.

1.4主管:

用于控制生成最终产品对象算法的类.主管对象会被实例化,并且它生成产品的对象方法被调用.方法中包含一个用于捕获生成产品的特定具体生成器对象.主管以正确的顺序调用具体生成器中的方法,从而生成产品对象.

1.5客户端:

将某个生成器对象与主管类相关联.

2.使用场景:

2.1开发者希望创建不同形式的产品,可以使用生成器.

2.2需要使用构造函数,并且参数很多.

2.3构造同一个对象的不同表示时,可以使用生成器模式.

3.具体实现:

3.1生成器接口:

go 复制代码
// 生成器接口.
type Builder interface {
	Build()
}

3.2具体生成器类:

go 复制代码
// 具体生成器类.用于构建产品的生成器.
type ConcreteBuilder struct {
	result CreateProduct
}

// 初始化具体生成器对象
func NewConcreateBuilder() ConcreteBuilder {
	return ConcreteBuilder{result: CreateProduct{}}
}

// 生成产品
func (b *ConcreteBuilder) Build() {
	b.result = CreateProduct{}
}

3.3生成器其他方法:

go 复制代码
// 返回在生产步骤中生成的产品对象.
func (b *ConcreteBuilder) GetResult() CreateProduct {
	return CreateProduct{true}
}

// 产品类
type CreateProduct struct {
	Built bool
}

3.4主管类:

go 复制代码
// 主管类.
type Director struct {
	builder Builder
}

//初始化主管对象.
func NewDirector(builder Builder) Director {
	return Director{builder}
}
//生成产品对象.
func (d Director) Construct() {
	d.builder.Build()
}

3.5客户端:

css 复制代码
func main() {
	builder := itboStudy.NewConcreateBuilder()
	director := itboStudy.NewDirector(&builder)
	director.Construct()
	result := builder.GetResult()
	fmt.Printf("result: %v\n", result)
}

4.实战:

4.1生成器接口:

scss 复制代码
// 生成器接口
type InterfaceBuilder interface {
	SetSeatsType()
	SetEngineType()
	SetNumber()
	GetCar() Car
}

// 获取生成器对象
func GetBuilder(BuilderType string) InterfaceBuilder {
	if BuilderType == "suv" {
		return NewSuvBuilder()
	}
	return nil
}

4.2具体生成器类:

go 复制代码
func NewSuvBuilder() *SuvBuilder {
	return &SuvBuilder{}
}

func (b *SuvBuilder) SetSeatsType() {
	b.SeatsType = "Suv座椅"
}

func (b *SuvBuilder) SetEngineType() {
	b.EngineType = "Suv引擎"
}

func (b *SuvBuilder) SetNumber() {
	b.Number = 5
}

func (b *SuvBuilder) GetCar() Car {
	return Car{
		SeatsType:  b.SeatsType,
		EngineType: b.EngineType,
		Number:     b.Number,
	}
}

4.3产品类:

go 复制代码
/ 产品类
type Car struct {
	SeatsType  string
	EngineType string
	Number     int
}

4.4主管类:

scss 复制代码
// 主管类
type Director struct {
	Builder InterfaceBuilder
}

func NewDirector(b InterfaceBuilder) *Director {
	return &Director{
		Builder: b,
	}
}

func (d *Director) SetBuilder(b InterfaceBuilder) {
	d.Builder = b
}

func (d *Director) BuildCar() Car {
	d.Builder.SetSeatsType()
	d.Builder.SetEngineType()
	d.Builder.SetNumber()
	return d.Builder.GetCar()
}

4.5客户端:

css 复制代码
func main() {
	builder := itboStudy.GetBuilder("suv")
	director := itboStudy.NewDirector(builder)
	car := director.BuildCar()
	fmt.Println(car)
}

5.优点:

产品内部组成细节对客户端不可见.产品的创建过程和产品解耦.

具体生成器相对独立.

将复杂产品创建步骤分解在不同的方法中,使创建过程更清晰更易于使用程序控制.

6缺点:

创建的产品组成部分类似,差异很大,不适合使用,所以适用范围有限.

需要为不同类型的产品创建单独的具体生成器,代码量大.

相关推荐
长栎1 小时前
你的订单状态机写成 switch-case 了?State 模式跟策略模式差了一个维度
后端
Zane19941 小时前
线程池进阶:如何科学设置线程数(结合实际业务场景复盘)
java·后端
晴殇i1 小时前
用 TRAE Work 搞定客户项目介绍,开发再也不用头疼写汇报 PPT
前端·后端
Cache技术分享1 小时前
488. Java 反射 - 动态创建数组
前端·后端
苏三说技术1 小时前
LangChain4j 入门指南
后端
Arvid1 小时前
MCP 协议史上最大更新:从有状态走向无状态
后端
程序员爱钓鱼2 小时前
Go 布尔类型 bool 详解
后端·面试·go
程序员爱钓鱼2 小时前
Rust Clone详解:深拷贝、复制成本与正确使用方式
后端·面试·rust