建造者模式-Go

本文深入探讨了建造者模式在Go语言中的应用,通过一个整车制造的例子,详细解释了如何将复杂的对象创建过程抽象出来,实现创建和使用的分离,以及如何在多个对象间重用对象创建方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

建造者模式——接口多种实现的重用方法

描述

对象的创建可以简单到只有花括号{},也可以复杂到需要调用API,检查状态,为属性创建对象。在Go语言中不支持继承,复用的特性则来自多个结构体的组合,所以一个对象的实例化需要多个对象组合在一起。

与此同时,你可能需要基本相同的技术去创建许多不同类型的对象。例如建造一辆轿车和一辆巴士的技术基本相同,不同的仅仅是车的大小,座位数等等,为了重用建造过程,就有了建造者模式。

预期目标

  • 将复杂的创建抽象出来,把创建和使用分开
  • 通过一步一步填充属性和内嵌对象来创建一个对象
  • 在多个对象之间重用对象创建方法

例子

建造者模式基本上可以概括为一个指导人几个建造者和他们产出的产品之间的关系。

下面介绍一个整车制造的例子

对于造一辆车来说,或多或少都有相同的工序,例如选择车辆的类型、整合车架、放置轮胎和放置座椅等等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BfbO6lop-1583218684656)(UML.jpg)]

首先我们定义需要产出的车辆的结构体,一个名为VehicleProduct的结构体,包括轮胎、座椅和车架三个部分。

type VehicleProduct struct {
	Wheels    int
	Seats     int
	Structure string
}

然后我们定义一个产生VechicleProduct的建造工序BuildProcessBuildProcess是一个接口,定义了三个装配方法返回中间产物和一个建造方法返回最终产物。

type BuildProcess interface {
	SetWheels() BuildProcess
	SetSeats() BuildProcess
	SetStructure() BuildProcess
	Build() VehicleProduct
}

然后我们定义一个指导人ManufacturingDirector,指导人有一个属性保存了BuilderProcess,对应着本次生产应该基于哪一种具体要求。同时提供一个SetBuilder()方法,设置当前BuilderProcess,以及一个Construct()方法,依次调用BuilderProcess的各个方法,完成整车制造。

type ManufacturingDirector struct {
	builder BuildProcess
}

func (f *ManufacturingDirector) Construct() {
	f.builder.SetSeats().SetStructure().SetWheels()
}

func (f *ManufacturingDirector) SetBuilder(b BuildProcess) {
	f.builder = b
}

最后我们定义一个具体的小轿车的制造方法,实现BuildProcess接口,定义一些具体的特定的工作。其中SetWheelsSetSeatsSetStructure三个方法是加工过程,可见返回类型为BuildProcess,最后的Build方法返回值则为真正出厂的产品。

type CarBuilder struct {
	v VehicleProduct
}

func (c *CarBuilder) SetWheels() BuildProcess {
	c.v.Wheels = 4
	return c
}

func (c *CarBuilder) SetSeats() BuildProcess {
	c.v.Seats = 5
	return c
}

func (c *CarBuilder) SetStructure() BuildProcess {
	c.v.Structure = "Car"
	return c
}

func (c *CarBuilder) Build() VehicleProduct {
	return c.v
}

测试

func TestBuilderPattern(t *testing.T) {
	manufacturingComplex := ManufacturingDirector{}

	carBuilder := &CarBuilder{}
	manufacturingComplex.SetBuilder(carBuilder)
	manufacturingComplex.Construct()

	car := carBuilder.Build()

	if car.Wheels != 4 {
		t.Errorf("Wheels on a car must be 4 and they were %d\n", car.Wheels)
	}

	if car.Structure != "Car" {
		t.Errorf("Structure on a car must be 'Car' and was %s\n", car.Structure)
	}

	if car.Seats != 5 {
		t.Errorf("Seats on a car must be 5 and they were %d\n", car.Seats)
	}

	bikeBuilder := &BikeBuilder{}
	manufacturingComplex.SetBuilder(bikeBuilder)
	manufacturingComplex.Construct()

	motorbike := bikeBuilder.Build()

	if motorbike.Wheels != 2 {
		t.Errorf("Wheels on a motorbike must be 2 and they were %d\n", motorbike.Wheels)
	}

	if motorbike.Structure != "Motorbike" {
		t.Errorf("Structure on a motorbike must be 'Motorbike' and was %s\n", motorbike.Structure)
	}

	if motorbike.Seats != 2 {
		t.Errorf("Seats on a motorbike must be 2 and they were %d\n", motorbike.Seats)
	}
}

运行结果

$go test -v
=== RUN   TestBuilderPattern
--- PASS: TestBuilderPattern (0.00s)
PASS
ok      github.com/ricardoliu404/go-design-patterns/creational/builder  0.141s

源码见https://github.com/ricardoliu404/go-design-patterns/tree/master/creational/builder

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值