发布日期

GoLang 设计模式之建造者模式 (Builder Pattern)

软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设 计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。

👷 建造者模式

在 Golang 中:当一个方法有多个变量的时候,我们在调用该方法的时候可能会因为参数的顺序、个数错误,而造成调用错误或者不能达到我们预期的目的。针对这个问题,我们的建造设计模式可以完美的解决这个问题

代码实现 (源码

package examples

import "fmt"

// 场景
// 现在需要生产一个汉堡
// 生产过程包括增加香肠,生菜,奶酪,番茄
// 且有固定的顺序,即必须先确定香肠,再确定生菜,奶酪,最后放番茄的顺序,顺序错了,
// 或者是少了其中任意一个步骤都不能做好一个汉堡。

// Burger 产品汉堡包
type Burger struct {
    // 香肠
    Pepperoni string
    // 🧀️
    Cheese string
    // 🥬
    Lettuce string
    // 🍅
    Tomato string
}

// GetDescription 获取描述
func (burger *Burger) GetDescription() {
    fmt.Printf("Burger 的成分是: %v,%v,%v,%v \n", burger.Pepperoni, burger.Cheese, burger.Lettuce, burger.Tomato)
}

// Builder 构建器接口
type Builder interface {
    AddPepperoni(Pepperoni string) Builder
    AddCheese(Cheese string) Builder
    AddLettuce(Lettuce string) Builder
    AddTomato(Tomato string) Builder
    Build() *Burger
}

// BurgerBuilder 具体的建造者
type BurgerBuilder struct {
    burger *Burger
}

// AddPepperoni 添加香肠
func (burgerBuilder *BurgerBuilder) AddPepperoni(Pepperoni string) Builder {
    burgerBuilder.burger.Pepperoni = Pepperoni
    return burgerBuilder
}

// AddCheese 添加 🧀️
func (burgerBuilder *BurgerBuilder) AddCheese(Cheese string) Builder {
    burgerBuilder.burger.Cheese = Cheese
    return burgerBuilder
}

// AddLettuce 添加 🥬
func (burgerBuilder *BurgerBuilder) AddLettuce(Lettuce string) Builder {
    burgerBuilder.burger.Lettuce = Lettuce
    return burgerBuilder
}

// AddTomato 添加 🍅
func (burgerBuilder *BurgerBuilder) AddTomato(Tomato string) Builder {
    burgerBuilder.burger.Tomato = Tomato
    return burgerBuilder
}

// Build 构建函数
func (burgerBuilder *BurgerBuilder) Build() *Burger {
    if burgerBuilder.burger.Pepperoni == "" || burgerBuilder.burger.Cheese == "" || burgerBuilder.burger.Lettuce == "" || burgerBuilder.burger.Tomato == "" {
        fmt.Println("🍔 成分不全,制作失败!")
        return nil
    }
    return burgerBuilder.burger
}

// NewBurgerBuilder 创建一个面包构建器
func NewBurgerBuilder() *BurgerBuilder {
    return &BurgerBuilder{&Burger{}}
}

测试用例(源码

package examples

import (
    "testing"
)

// TestBuilder 测试
// command: go test -v builder_test.go builder.go
func TestBuilder(t *testing.T) {

    t.Log("制作第一个 🍔")
    burger1 := NewBurgerBuilder().AddPepperoni("火腿1").AddCheese("奶酪1").AddLettuce("生菜1").AddTomato("番茄1").Build()

    if burger1.Pepperoni != "火腿1" || burger1.Cheese != "奶酪1" || burger1.Lettuce != "生菜1" || burger1.Tomato != "番茄1" {
        t.Fail()
    }

    t.Log("制作第二个 🍔")
    burger2 := NewBurgerBuilder().AddPepperoni("火腿2").AddCheese("奶酪2").AddLettuce("生菜2").AddTomato("番茄2").Build()

    if burger2.Pepperoni != "火腿2" || burger2.Cheese != "奶酪2" || burger2.Lettuce != "生菜2" || burger2.Tomato != "番茄2" {
        t.Fail()
    }

    t.Log("制作第三个 🍔")
    burger3 := NewBurgerBuilder().AddPepperoni("火腿3").AddLettuce("生菜3").AddTomato("番茄3").Build()
    if burger3 != nil {
        t.Fail()
    }
}

注意

  • 设计模式不是解决所有问题的灵丹妙药。

  • 不要试图强迫他们; 如果这样做的话,应该发生坏事。

  • 请记住,设计模式是问题的解决方案,而不是解决问题的解决方案;所以不要过分思考。

  • 如果以正确的方式在正确的地方使用,他们可以证明是救世主; 否则他们可能会导致代码混乱。

声明

备案号:湘ICP备2020019075号 © 2020 yxx All rights reserved. | my github