可配置的字段验证和默认值

问题描述 投票:0回答:1

考虑这个结构:

type Intervals struct {
    DefaultDuration time.Duration
    FailDuration    time.Duration
}

我们还假设持续时间列表将来可能会扩展。

它用于一个简单的 CRUD API,可让您更改这些持续时间(如

SetDefaultDuration
)。因此,我们希望验证设置请求中的值,并设置一些默认值。但是,如果我们想使用一些外部配置来配置验证,并以相同的方式配置默认值,该怎么办?例如:

  • DefaultDuration
    应大于1s,无默认值
  • FailDuration
    应介于 5 秒到 30 秒之间,默认值为 15 秒

那么,问题是 - 在 Go 中哪些方法适合解决这个问题?

似乎为每个持续时间类型(以及类型本身)定义工厂应该可行,但我认为太冗长了。这是例子:

type FailDuration time.Duration

type FailDurationFactory struct {
    defaultValue time.Duration
    minValue     time.Duration
}

func NewFactory(cfg Config) (FailDurationFactory, error) {
    // build from the cfg
}

func (f FailDurationFactory) New(d time.Duration) (FailDuration, error) {
    // set default & validate & return
}

Config
可以从文件加载,例如,在应用程序启动时从 JSON 解组。

go validation design-patterns configuration default
1个回答
0
投票

这看起来像是功能选项的用例。

按照 Uber Go 风格指南的风格实现,可能看起来像这样(Go Playground):

package main

import (
    "fmt"
    "time"
)

type intervals struct {
    defaultDuration time.Duration
    failDuration    time.Duration
}

type Interval interface {
    apply(*intervals)
}

type defaultDuration time.Duration

func (d defaultDuration) apply(i *intervals) {
    i.defaultDuration = time.Duration(d)
}

func WithDefaultDuration(d time.Duration) Interval {
    return defaultDuration(d)
}

type failDuration time.Duration

func (f failDuration) apply(i *intervals) {
    i.failDuration = time.Duration(f)
}

func WithFailDuration(d time.Duration) Interval {
    return failDuration(d)
}

const DefaultFailDuration = 5 * time.Second

func DoSomething(
    ivs ...Interval,
) {
    iv := intervals{
        failDuration: DefaultFailDuration,
    }

    for _, i := range ivs {
        i.apply(&iv)
    }

    fmt.Printf("%#v\n", iv)
}

func main() {
    DoSomething()

    DoSomething(WithDefaultDuration(100 * time.Millisecond))

    DoSomething(WithDefaultDuration(100*time.Millisecond), WithFailDuration(15*time.Second))
}

当然,您可以根据您的用例调整样式。

© www.soinside.com 2019 - 2024. All rights reserved.