Go 设计模式之 Options-Pattern

  1. 结构体
  2. 通过构造函数(Constructor)装配属性
  3. 通过 func 作为参数传入构造函数
    1. 参考资料:

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]

Title:Go 设计模式之 Options-Pattern

Count:391

Author:nickChen

Created At:2020-12-28, 10:36:01

Updated At:2023-05-08, 23:27:10

Url:http://nickchenyx.github.io/2020/12/28/go-pattern-options/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.