在Go中构建复杂对象: 构建器模式指南

本文我们介绍了构建器模式,介绍了如何通过构建器对象构建复杂业务对象的方法。
首页 新闻资讯 行业资讯 在Go中构建复杂对象: 构建器模式指南

构建具有许多可选参数的复杂对象可能是一项艰巨的任务。

当处理具有许多可选参数的对象时,传统构造函数和setter方法会变得很麻烦。

本文将探讨构建器模式(builder pattern),这是一种允许创建具有许多可选参数的复杂对象的设计模式。

3158ba745ddde95b6d6880d07cf0b5bed5f0e7.jpg

我们将介绍基于Go的构建器模式示例实现,并讨论如何创建同一对象的不同变体。

+----------------++-------------------+|Director|directs|Builder|+----------------++-------------------+|construct()|------------>|buildPart1()||setBuilder()||buildPart2()|+----------------+|getProduct()|+-------------------+|V+-------------------+|Product|+-------------------+|field1||field2||...|+-------------------+

在Go中实现构建器模式

下面是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=makereturncb}func(cb*CarBuilder)SetModel(model string)*CarBuilder{cb.Model=modelreturncb}func(cb*CarBuilder)SetYear(year int)*CarBuilder{cb.Year=yearreturncb}func(cb*CarBuilder)SetColor(color string)*CarBuilder{cb.Color=colorreturncb}func(cb*CarBuilder)SetEngineSize(engineSize float64)*CarBuilder{cb.EngineSize=engineSizereturncb}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中构建器模式的高级用例

构建器模式有一些高级用例,可以在某些情况下使用。

下面介绍Go中构建器模式的一些高级用例。

创建构建器接口

在构建器模式基本示例中,有一个用于构建对象的builder结构。

不过我们可以创建builder接口,让不同builder结构实现其接口。

当我们需要使用相同模式构建不同类型的对象时,这非常有用。

假设有两种类型的汽车: 电动汽车和汽油汽车,有相同的可选参数,但有不同的必需参数。

在这种情况下,可以创建一个CarBuilder接口,指定构建汽车所需的方法,然后创建两个实现CarBuilder接口的结构: ElectricCarBuilder和GasolineCarBuilder。

type CarBuilderinterface{SetMake(make string)CarBuilderSetModel(model string)CarBuilderSetYear(year int)CarBuilderSetColor(color string)CarBuilderSetEngineSize(engineSize float64)CarBuilderBuild()Car}type ElectricCarBuilder struct{Car}type GasolineCarBuilder struct{Car}

ElectricCarBuilder和GaslineCarBuilder都嵌入了Car结构体并实现了CarBuilder接口。

然后可以自己实现制造汽车所需的方法。

func(b*ElectricCarBuilder)SetMake(make string)CarBuilder{b.Make=makereturnb}func(b*ElectricCarBuilder)SetModel(model string)CarBuilder{b.Model=modelreturnb}func(b*ElectricCarBuilder)SetYear(year int)CarBuilder{b.Year=yearreturnb}func(b*ElectricCarBuilder)SetColor(color string)CarBuilder{b.Color=colorreturnb}func(b*ElectricCarBuilder)SetEngineSize(engineSize float64)CarBuilder{b.EngineSize=engineSizereturnb}func(b*ElectricCarBuilder)Build()Car{returnb.Car}func(b*GasolineCarBuilder)SetMake(make string)CarBuilder{b.Make=makereturnb}func(b*GasolineCarBuilder)SetModel(model string)CarBuilder{b.Model=modelreturnb}func(b*GasolineCarBuilder)SetYear(year int)CarBuilder{b.Year=yearreturnb}func(b*GasolineCarBuilder)SetColor(color string)CarBuilder{b.Color=colorreturnb}func(b*GasolineCarBuilder)SetEngineSize(engineSize float64)CarBuilder{b.EngineSize=engineSizereturnb}func(b*GasolineCarBuilder)Build()Car{returnb.Car}

我们因此可以基于接口创建汽车,也可以使用相同的接口做模拟。

funcCreateCar(builder CarBuilder)Car{returnbuilder.SetMake("Toyota").SetModel("Corolla").SetYear(2022).SetColor("blue").SetEngineSize(2.0).Build()}funcmain(){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

13    2024-01-15 06:11:13    Go 构建器模式 开发