创建型 建造者模式

为什么需要建造者模式

很多时候我们创建了类的对象,或者创建以后一般会定义set函数进行修改,这种思路一般是okay的,但是有下面这些特殊情况,我们需要检查输入参数之间的依赖关系或者想构建一个不能被修改的对象,这种情况,我们可以考虑采用建造者模式。

建造者模式实现

就是我们需要构建一个单独的builder类来临时储存输入变量然后进行校正,如果输入变量不符合要求,拒绝生成使用对象。

go.mod

module builder

go 1.13

builder.go

package builder

import "fmt"

type Square struct {
	height int
	width  int
}

func (s *Square) Validate() bool {
	return s.height == s.width
}

type SquareBuilder struct {
	height int
	width  int
}

func (s *SquareBuilder) SetHeight(height int) *SquareBuilder {
	s.height = height
	return s
}

func (s *SquareBuilder) SetWidth(width int) *SquareBuilder {
	s.width = width
	return s
}

func (s *SquareBuilder) BuildSquare() (*Square, error) {
	if s.height == 0 || s.width == 0 || s.height != s.width {
		return nil, fmt.Errorf("height %d is not the same as width %d", s.height, s.width)
	}
	return &Square{height: s.height, width: s.width}, nil
}

builder_test.go

package builder_test

import (
	"builder"
	"testing"
)

func TestBuilder(t *testing.T) {
	sqBuilder := builder.SquareBuilder{}
	_, err := sqBuilder.SetHeight(10).SetWidth(9).BuildSquare()
	if err == nil {
		t.Fatal("Expecting building error but not get it")
	}

	perfectSquare, err := sqBuilder.SetHeight(20).SetWidth(20).BuildSquare()
	if err != nil {
		t.Fatal("Does not expect build error")
	}
	if !perfectSquare.Validate() {
		t.Fatal("Incorrect square is built")
	}
}

执行: go test builder -v

Previous
Next