Options Pattern 主要是使用于装配属性,让我们先来看看传统的属性装配方案。
结构体
type House struct {
Material string
HasFireplace bool
Floors int
}
通过构造函数(Constructor)装配属性
// NewHouse("concrete", 5, true)
func NewHouse(m string, f int, fp bool) *House {
return &House {
Material: m,
HasFireplace: fp,
Floors: f,
}
}
可以看到此时通过一个自定义的构造函数装配属性,此时需装配的属性需要一次性全部填入,且构造函数的入参有顺序性,必须按照函数定义的顺序传入参数。另外,当需装配的属性过于多时,此时构造函数也会越来越冗长。
通过 func 作为参数传入构造函数
type HouseOption func(*House)
func WithConcrete() HouseOption {
return func(h *House) {
h.Material = "concrete"
}
}
func WithoutFireplace() HouseOption {
return func(h *House) {
h.HasFireplace = false
}
}
func WithFloors(floors int) HouseOption {
return func(h *House) {
h.Floors = floors
}
}
func NewHouse(opts ...HouseOption) *House {
const (
defaultFloors = 2
defaultHasFireplace = true
defaultMaterial = "wood"
)
h := &House{
Material: defaultMaterial,
HasFireplace: defaultHasFireplace,
Floors: defaultFloors,
}
// Loop through each option
for _, opt := range opts {
// Call the option giving the instantiated
// *House as the argument
opt(h)
}
// return the modified house instance
return h
}
// build House with options
h := NewHouse(
WithConcrete(),
WithoutFireplace(),
WithFloors(3),
)
将 func 作为参数传入,一是方便了装配属性的复杂配置,二是不需要固定顺序的构造参数传入,三其实这样的实现方式也可以作为一个属性装配的切面,可以暗搓搓整点活儿。
这就是 Options Patter 了。
参考资料:
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 [email protected]