如何在Golang中实现功能选项或选项模式(附实例)

215 阅读1分钟

假设你有一个函数,它返回一个带有/不带有默认值的对象到其字段。这就像一个构造函数。如果你想在第一次创建对象实例时覆盖默认值,怎么办?这就是功能选项的用武之地。你的函数以某种方式和结构接受额外的参数。这些参数就会覆盖只与它们相关的字段,而不是所有其他的字段!见下面的例子:

package main

import (
	"fmt"
)

type Car struct {
	make   string
	model  string
	colour string
}

func NewCar() *Car {
	return &Car{
		make:   "BMW",
		model:  "3.18",
		colour: "Silver",
	}
}

func main() {
	car := NewCar()

	fmt.Printf("%+v\n", car)
}

这就是我们得到的东西,现在看来是没有用的:

&{make:BMW model:3.18 colour:Silver}

功能性选项

现在让我们应用Options Pattern来使Car 结构在初始化时开放修改:

package main

import (
	"fmt"
)

type Car struct {
	make   string
	model  string
	colour string
}

type Option func(*Car)

func Make(v string) Option {
	return func(c *Car) {
		c.make = v
	}
}
func Model(v string) Option {
	return func(c *Car) {
		c.model = v
	}
}
func Colour(v string) Option {
	return func(c *Car) {
		c.colour = v
	}
}

func NewCar(opts... Option) *Car {
	c := &Car{
		make:   "BMW",
		model:  "3.18",
		colour: "Silver",
	}

	for _, opt := range opts {
		opt(c)
	}
	
	return c
}

func main() {
	car1 := NewCar()
	fmt.Printf("%+v\n", car1)

	car2 := NewCar(Make("Mercedes"), Model("SEL 500"))
	fmt.Printf("%+v\n", car2)
}

这就是我们现在得到的东西,它是高度可定制的,我们将颜色保持不变:

&{make:BMW model:3.18 colour:Silver}
&{make:Mercedes model:SEL 500 colour:Silver}