go - 设置 Option 对象时不可变 setter 和传统 setter 的区别

标签 go design-patterns setter

在研究了一段时间的开源项目之后,我经常在一个类的设置选项中看到这种模式。 (让我们说“不可变方法”)

// list of possible options
type Options struct {
    Sampler sampler
    SpanKind int
}

// define an apply function. which will be called when really initialize an object
type Option func(*Options)

// for each option. Return an function to apply that specific option
func WithSpanKind(spanKind int) Option {
    return func(o *Options) {
        o.SpanKind = spanKind
    }
}

// then. we we build a new object, we just need to receive a list of option
func NewObject(options ...Option) Object {
     final := &Options{}
     // then apply each option to options
     for _, option := range options {
         option(final)
     }
     // then build an object based on the final object
}

与上述方法相比,还有另一种使用简单 getter/setter 的方法。
func (o *Options) SetSpanKind(kind int) {
   o.spanKind = kind
}

// then. we we build a new object by using directly the Options object
func NewObject(option Options) Object {
}

我的问题是:这些方法之间有什么区别,为什么在我读过的许多开源代码中总是首选第一种方法。

注意:这里有一些开源代码,其中包含实现上述模式的行。这些开源是由谷歌发起的,所以也许这种模式只特定于谷歌。
  • Golang GRPC - DialOption
  • OpenCensus - TraceOption

  • 谢谢

    最佳答案

    至少在 Golang 中,getter 的使用是一种反模式。这种期权模式是众所周知的。 Setter 和 getter 在 Golang 空间中并不常见。

    此选项模式有一个不错的好处,您可以将多个选项函数传递给您的构建器或构造函数,然后遍历所有传递的选项以修改此选项类型,就像在您的示例中一样

    // then. we build a new object, we just need to receive a list of option
    func NewObject(options ...Option) Object {
         final := &Options{}
         // then apply each option to options
         for _, option := range options {
             option(final)
         }
         // then build an object based on the final object
    }
    

    构造函数调用示例:
    NewObject(optionA, optionB, optionC, optionD)
    

    getter 和 setter

    https://golang.org/doc/effective_go.html#Getters

    你肯定读过有效的围棋指南 -> https://golang.org/doc/effective_go.html

    关于go - 设置 Option 对象时不可变 setter 和传统 setter 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59799857/

    相关文章:

    pointers - 调用结构属性方法时 Golang 结构指针引用丢失

    html - 在 Go 中解析 HTML 输入标签

    java - 我应该在 DTO 中使用构建器模式吗?

    design-patterns - GOF 和 GRASP 设计模式有什么区别

    java - OO 设计问题接口(interface)和类

    c# - 私有(private) setter 不会阻止更改数组元素

    go - ParseInt() 中使用的基本参数是什么?

    go - labstack/echo 中参数后的静态 URL 路径是否有效

    java - 如何为这个 Kotlin 类属性使用 setter?

    loopbackjs - Loopback.io 中的属性 setter 和 getter