Различия между неизменным и традиционным установщиками при настройке объекта Option - PullRequest
0 голосов
/ 18 января 2020

После некоторого времени изучения проектов с открытым исходным кодом я часто вижу шаблон в параметрах настройки для класса. (Пусть, скажем, «неизменяемый метод»)

// 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
}

По сравнению с вышеописанным методом, есть еще один способ использования простого метода получения / установки.

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 {
}

Мой вопрос: каковы различия между этими подходами и почему первый подход всегда предпочитается во многих открытых источниках, которые я прочитал.

Отмечено: Вот некоторые открытые источники с линией, которая реализует вышеупомянутый образец. Эти открытые источники инициированы Google, поэтому, возможно, этот шаблон указывает только c только на Google.

Спасибо

1 Ответ

1 голос
/ 18 января 2020

По крайней мере, в Golang использование геттеров является анти-паттерном. Этот вариант шаблона очень хорошо известен. Сеттеры и геттеры не очень распространены в пространстве 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)

Получатели и сеттеры

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

Вы определенно прочитали действующие рекомендации go -> https://golang.org/doc/effective_go.html

...