Golang Options Design Patterns

Introducing problems: a conventional structure, then declare a constructor method for initializing the structure, the structure of the field for the assignment

package main

import "fmt"

// 声明options结构体
type Options struct {
    str1 string
    str2 string
    int1 int
    int2 int
}

// 声明构造方法进行初始化结构体
func InitOptions() *Options {
    return &Options{}
}

func main() {
    options := InitOptions()
    fmt.Printf("%#v", options)
}

Common method to achieve

Each of the field declaration structure, and were compared to at construction fields and location of the structural body

package main

import "fmt"

// 声明options结构体
type Options struct {
    str1 string
    str2 string
    int1 int
    int2 int
}

// 声明构造方法进行初始化结构体
func InitOptions(str1 string, str2 string, int1 int, int2 int) *Options {
    options := &Options{}
    options.str1 = str1
    options.str2 = str2
    options.int1 = int1
    options.int2 = int2
    return options
}

func main() {
    options := InitOptions("a", "b", 1, 2)
    fmt.Printf("%#v", options)
}

The problem with this approach: When the structure of each additional fields need to be modified on the line of the constructor, and the uncertainty of the structure increases the number of fields and field types, if you want to modify this approach of looking at the more cumbersome but looking at the code is relatively low

The second longhand

Type and number of fields of view field above wording is uncertain, we can become a variable parameter configured transmission mode parameters, a parameter is passed and interfacetype, then a parameter by traversing the structure assignment

package main

import "fmt"

// 声明options结构体
type Options struct {
    str1 string
    str2 string
    int1 int
    int2 int
}

// 声明构造方法进行初始化结构体
func InitOptions(opts ...interface{}) *Options {
    options := &Options{}
    for index, val := range opts {
        switch index {
        case 1:
            v, _ := val.(string)
            options.str1 = v
        case 2:
            v, _ := val.(string)
            options.str2 = v
        case 3:
            v, _ := val.(int)
            options.int1 = v

        case 4:
            v, _ := val.(int)
            options.int2 = v
        }
    }

    return options
}

func main() {
    options := InitOptions("a", "b", 1, 2)
    fmt.Printf("%#v", options)
}

This approach is also looking at more complicated, but we identified the number and types of arguments constructor requires is uncertain, then we introduced the option to transform design patterns

Options design pattern

  1. Declare a Optionvariable type, and function as a type, a function pointer type receiving type Optionsstructure
  2. Constructor takes a variable-length Optionvariable type
  3. After not add a field to create a specified format type of function, passing the constructor to initialize structure

code show as below:

package main

import "fmt"

// 声明options结构体
type Options struct {
    str1 string
    str2 string
    int1 int
    int2 int
}

// 声明一个变量类型,变量接收一个Options结构体的指针类型
type Option func(opts *Options)

// 声明构造方法进行初始化结构体
func InitOptions(opts ...Option) *Options {
    options := &Options{}
    for _, opt := range opts {
        opt(options)
    }
    return options
}

func WithOptionStr1(str string) Option {
    return func(opts *Options) {
        opts.str1 = str
    }
}

func WithOptionStr2(str string) Option {
    return func(opts *Options) {
        opts.str2 = str
    }
}

func WithOptionInt1(i int) Option {
    return func(opts *Options) {
        opts.int1 = i
    }
}

func WithOptionInt2(i int) Option {
    return func(opts *Options) {
        opts.int2 = i
    }
}

func main() {
    options := InitOptions(
        WithOptionStr1("a"),
        WithOptionStr2("b"),
        WithOptionInt1(1),
        WithOptionInt2(2),
    )
    fmt.Printf("%#v", options)
}

Guess you like

Origin www.cnblogs.com/zhichaoma/p/12509110.html
Recommended