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缺点:

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

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

相关推荐
++==11 分钟前
RESTful详解:核心思想、框架、与HTTP的区别,API的设计风格
后端·http·restful
IT_陈寒1 小时前
Vue的响应式更新有时候真的不听话
前端·人工智能·后端
向生2 小时前
Ubuntu Caddy 保姆级完整教程
后端
tntxia2 小时前
Docker权限的问题
后端
明月_清风2 小时前
看完这段关于"全插件化架构"的技术分析后,我整理了一份笔记
前端·后端
摇滚侠3 小时前
《SpringBoot 3:入门与应用实战》第 7 章 AOP 思想与实现 阅读笔记 14
spring boot·笔记·后端
她的男孩3 小时前
我把管理系统接给AI,它改条数据都要先问我
java·后端·架构
元界metalite3 小时前
SpringBoot分页接口怎么设计-pageSize不设上限会发生什么
后端
IT爱学堂4 小时前
Go开发疑难杂症终结者通关指南
后端
大勇前进5 小时前
从10分钟到10秒:一个真实慢查询的SQL Server优化全记录
后端