构建具有许多可选参数的复杂对象可能是一项艰巨的任务。
当处理具有许多可选参数的对象时,传统构造函数和setter方法会变得很麻烦。
本文将探讨构建器模式(builder pattern),这是一种允许创建具有许多可选参数的复杂对象的设计模式。
我们将介绍基于Go的构建器模式示例实现,并讨论如何创建同一对象的不同变体。
+----------------+ +-------------------+| Director | directs | Builder |+----------------+ +-------------------+| construct() | ------------> | buildPart1() || setBuilder() | | buildPart2() |+----------------+ | getProduct() | +-------------------+ | V +-------------------+ | Product | +-------------------+ | field1 | | field2 | | ... | +-------------------+
下面是golang中构建器模式示例:
type Car struct { Make string Model string Year int Color string EngineSize float64}type CarBuilder struct { Car}func (cb *CarBuilder) SetMake(make string) *CarBuilder { cb.Make = make return cb}func (cb *CarBuilder) SetModel(model string) *CarBuilder { cb.Model = model return cb}func (cb *CarBuilder) SetYear(year int) *CarBuilder { cb.Year = year return cb}func (cb *CarBuilder) SetColor(color string) *CarBuilder { cb.Color = color return cb}func (cb *CarBuilder) SetEngineSize(engineSize float64) *CarBuilder { cb.EngineSize = engineSize return cb}func (cb *CarBuilder) Build() *Car { return &cb.Car}
CarBuilder结构嵌入了一个Car对象,所以它的所有字段都可以被构建器访问。
CarBuilder结构具有设置Car对象可选参数的方法,每个方法返回指向CarBuilder结构体的指针,以允许链式调用。
CarBuilder结构体上的Build方法返回指向被构建的Car对象的指针。
下面是使用CarBuilder的例子:
carBuilder := &CarBuilder{}car := carBuilder. SetMake("Toyota"). SetModel("Corolla"). SetYear(2021). SetColor("Red"). SetEngineSize(1.8). Build()fmt.Printf("Make: %s/n", car.Make) // Output: Make: Toyotafmt.Printf("Model: %s/n", car.Model) // Output: Model: Corollafmt.Printf("Year: %d/n", car.Year) // Output: Year: 2021fmt.Printf("Color: %s/n", car.Color) // Output: Color: Redfmt.Printf("Engine Size: %.1f/n", car.EngineSize) // Output: Engine Size: 1.8
在这个例子中,我们创建了一个CarBuilder对象,用它的方法来设置Car对象的可选参数。
最后调用Build方法来获取最终的Car对象。然后打印出Car对象的字段,以验证是否设置正确。
构建器模式有一些高级用例,可以在某些情况下使用。
下面介绍Go中构建器模式的一些高级用例。
在构建器模式基本示例中,有一个用于构建对象的builder结构。
不过我们可以创建builder接口,让不同builder结构实现其接口。
当我们需要使用相同模式构建不同类型的对象时,这非常有用。
假设有两种类型的汽车: 电动汽车和汽油汽车,有相同的可选参数,但有不同的必需参数。
在这种情况下,可以创建一个CarBuilder接口,指定构建汽车所需的方法,然后创建两个实现CarBuilder接口的结构: ElectricCarBuilder和GasolineCarBuilder。
type CarBuilder interface { SetMake(make string) CarBuilder SetModel(model string) CarBuilder SetYear(year int) CarBuilder SetColor(color string) CarBuilder SetEngineSize(engineSize float64) CarBuilder Build() Car}type ElectricCarBuilder struct { Car}type GasolineCarBuilder struct { Car}
ElectricCarBuilder和GaslineCarBuilder都嵌入了Car结构体并实现了CarBuilder接口。
然后可以自己实现制造汽车所需的方法。
func (b *ElectricCarBuilder) SetMake(make string) CarBuilder { b.Make = make return b}func (b *ElectricCarBuilder) SetModel(model string) CarBuilder { b.Model = model return b}func (b *ElectricCarBuilder) SetYear(year int) CarBuilder { b.Year = year return b}func (b *ElectricCarBuilder) SetColor(color string) CarBuilder { b.Color = color return b}func (b *ElectricCarBuilder) SetEngineSize(engineSize float64) CarBuilder { b.EngineSize = engineSize return b}func (b *ElectricCarBuilder) Build() Car { return b.Car}func (b *GasolineCarBuilder) SetMake(make string) CarBuilder { b.Make = make return b}func (b *GasolineCarBuilder) SetModel(model string) CarBuilder { b.Model = model return b}func (b *GasolineCarBuilder) SetYear(year int) CarBuilder { b.Year = year return b}func (b *GasolineCarBuilder) SetColor(color string) CarBuilder { b.Color = color return b}func (b *GasolineCarBuilder) SetEngineSize(engineSize float64) CarBuilder { b.EngineSize = engineSize return b}func (b *GasolineCarBuilder) Build() Car { return b.Car}
我们因此可以基于接口创建汽车,也可以使用相同的接口做模拟。
func CreateCar(builder CarBuilder) Car { return builder. SetMake("Toyota"). SetModel("Corolla"). SetYear(2022). SetColor("blue"). SetEngineSize(2.0). Build()}func main() { electricCarBuilder := &ElectricCarBuilder{} gasolineCarBuilder := &GasolineCarBuilder{} electricCar := CreateCar(electricCarBuilder) gasolineCar := CreateCar(gasolineCarBuilder) fmt.Printf("Electric car: %+v/n", electricCar) fmt.Printf("Gasoline car: %+v/n", gasolineCar)}
在本例中,我们创建了ElectricCarBuilder和GasolineCarBuilder,并分别创建了一辆电动车和一辆汽油车。
CreateCar函数接受CarBuilder接口,并在最后调用Build方法创建Car对象之前,使用构建器的方法设置必需的字段。
参考资料:
[1]Building Complex Objects in Go: A Guide to the Builder Pattern: https://dsysd-dev.medium.com/building-complex-objects-in-go-a-guide-to-the-builder-pattern-1a64bc0eb3ee
本文链接:http://www.28at.com/showinfo-26-60945-0.html在Go中构建复杂对象: 构建器模式指南
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 快速初始化容器化Gin项目