建造者模式(Builder Pattern)是一种创建型设计模式,它允许你逐步构造一个复杂对象,将构造过程和表示分离,从而可以创建具有不同属性组合的对象。
在Go语言中,你可以使用结构体和方法来实现建造者模式。
就想你去麦当劳 Or KFC点餐~ 你可以任意单点餐品,也可以选择不同餐品搭配的套餐!
但是每一种餐品都是单独制作出来的,将不同的单品搭配起来,就是不同的套餐了!
构建了两种不同类型的套餐,每种套餐都包含主餐、饮品和甜品小食。
package main
import "fmt"
// Product 表示点餐的餐点
type Product struct {
mainDish string // 主餐
drink string // 饮品
dessert string // 甜品小食
}
// Builder 接口定义了构建餐点的方法
type Builder interface {
BuildMainDish(MainDish string) Builder
BuildDrink(Drink string) Builder
BuildDessert(Dessert string) Builder
GetProduct() Product
}
// ProductPackage 表示由 Product 三件套组成的套餐!
type ProductPackage struct {
product Product
}
func (b *ProductPackage) BuildMainDish(MainDish string) Builder {
b.product.mainDish = MainDish // 主菜是猪柳蛋汉堡
// 建造者方法可以返回建造者自身,这样可以支持链式调用,使代码更简洁
return b
}
func (b *ProductPackage) BuildDrink(Drink string) Builder {
b.product.drink = Drink // 饮料
return b
}
func (b *ProductPackage) BuildDessert(Dessert string) Builder {
b.product.dessert = Dessert // 小食
return b
}
func (b *ProductPackage) GetProduct() Product {
return b.product
}
// 猪柳蛋麦满分套餐
type PorkTenderloinEggMcMuff struct {
builder Builder
}
func (d *PorkTenderloinEggMcMuff) Do() Product {
return d.builder.
BuildMainDish("PorkTenderloinEgg Burger").
BuildDrink("咖啡").
BuildDessert("紫薯饼").
GetProduct()
}
// 大脆鸡扒麦满分
type BigCrispyChickenChopWheat struct {
builder Builder
}
func (d *BigCrispyChickenChopWheat) Do() Product {
return d.builder.
BuildMainDish("BigCrispyChickenChopWheat Burger").
BuildDrink("豆浆").
BuildDessert("薯饼").
GetProduct()
}
func main() {
builder := &ProductPackage{}
porkTenderloinEggPkg := &PorkTenderloinEggMcMuff{builder: builder}
bigCrispyChickenChopWheat := &BigCrispyChickenChopWheat{builder: builder}
PorkTenderloinEggMcMuffMeal := porkTenderloinEggPkg.Do()
fmt.Println(" ============= 猪柳蛋麦满分 ========== ")
bigCrispyChickenChopWheatMeal := bigCrispyChickenChopWheat.Do()
fmt.Printf("Main Dish: %s\n", PorkTenderloinEggMcMuffMeal.mainDish)
fmt.Printf("Drink: %s\n", PorkTenderloinEggMcMuffMeal.drink)
fmt.Printf("Dessert: %s\n", PorkTenderloinEggMcMuffMeal.dessert)
fmt.Println(" ========== 大脆鸡扒麦满分 ========== ")
fmt.Printf("Main Dish: %s\n", bigCrispyChickenChopWheatMeal.mainDish)
fmt.Printf("Drink: %s\n", bigCrispyChickenChopWheatMeal.drink)
fmt.Printf("Dessert: %s\n", bigCrispyChickenChopWheatMeal.dessert)
}
代码中使用了不同的建造者实现来构建不同类型的套餐,然后通过调用各自的 Do
方法进行构建
使用建造者模式构建不同类型的套餐,每种套餐都由主餐、饮品和甜品小食组成。通过使用不同的建造者实现,可以灵活地构建不同的套餐组合
后续如果对套餐进行扩展,直接在产品新增品类,在Buider中新增新产品的制作方法就可以了
// Product 表示点餐的餐点
type Product struct {
mainDish string // 主餐
drink string // 饮品
dessert string // 甜品小食
+ Toy string // 玩具
}
// Builder 接口定义了构建餐点的方法
type Builder interface {
BuildMainDish(MainDish string) Builder
BuildDrink(Drink string) Builder
BuildDessert(Dessert string) Builder
+ BuildToy(Toy string) Builder
GetProduct() Product
}
定义儿童套餐
// 儿童欢乐套餐
type ChildHappyPackage struct {
builder Builder
}
func (d *ChildHappyPackage) Do() Product {
return d.builder.
BuildMainDish("ChildHappyPackage Burger").
BuildDrink("牛奶").
BuildDessert("薯条").
BuildToy("变形金刚").
GetProduct()
}
func main() {
builder := &ProductPackage{}
porkTenderloinEggPkg := &PorkTenderloinEggMcMuff{builder: builder}
bigCrispyChickenChopWheat := &BigCrispyChickenChopWheat{builder: builder}
PorkTenderloinEggMcMuffMeal := porkTenderloinEggPkg.Do()
bigCrispyChickenChopWheatMeal := bigCrispyChickenChopWheat.Do()
fmt.Println(" ============= 猪柳蛋麦满分 ========== ")
fmt.Printf("Main Dish: %s\n", PorkTenderloinEggMcMuffMeal.mainDish)
fmt.Printf("Drink: %s\n", PorkTenderloinEggMcMuffMeal.drink)
fmt.Printf("Dessert: %s\n", PorkTenderloinEggMcMuffMeal.dessert)
fmt.Println(" ========== 大脆鸡扒麦满分 ========== ")
fmt.Printf("Main Dish: %s\n", bigCrispyChickenChopWheatMeal.mainDish)
fmt.Printf("Drink: %s\n", bigCrispyChickenChopWheatMeal.drink)
fmt.Printf("Dessert: %s\n", bigCrispyChickenChopWheatMeal.dessert)
+ fmt.Println(" ========== 欢乐儿童套餐 ========== ")
+ childHappyPackage := &ChildHappyPackage{builder: builder}
+ childHappyPackageMeal := childHappyPackage.Do()
+ fmt.Printf("Main Dish: %s\n", childHappyPackageMeal.mainDish)
+ fmt.Printf("Drink: %s\n", childHappyPackageMeal.drink)
+ fmt.Printf("Dessert: %s\n", childHappyPackageMeal.dessert)
+ fmt.Printf("Dessert: %s\n", childHappyPackageMeal.Toy)
}
评论区