实例浅谈利用Golang的Builder&Option设计模式来传递初始化参数

2,013 阅读2分钟

GO语言函数不支持默认参数,想要支持默认参数,必须自己实现,但是想要实现优雅的传参模式,就要用到设计模式;以下使用Builder和Option设计模式来实现优雅的默认参数和传参。

函数Option模式

  • 创建OptionRedis结构体,Id为必须要指定的尝试,Option为默认参数结构体
  • 创建更改默认参数函数ModOption,便于修改默认参数
  • 创建每个默认参数修改的函数SetAddr,SetDb,SetPass
  • 构建初始化函数NewOptionRedis,指定默认参数的默认值,遍历加载修改默认参数的函数,以接受调用者更改后的参数,返回OptionRedis结构体
package redis

import "fmt"

type OptionRedis struct {
	Id     int
	Option Option
}
type Option struct {
	Addr     string
	Db       int
	Password string
}
type ModOption func(option *Option)

func SetAddr(addr string) ModOption   {
	return func(option *Option) {
		option.Addr=addr
	}
}
func SetDb(db int) ModOption  {
	return func(option *Option) {
		option.Db=db
	}
}
func SetPass(pwd string) ModOption {
	return func(option *Option) {
		option.Password=pwd
	}
}
func NewOptionRedis(id int,modoption ...ModOption) *OptionRedis  {
	option := Option{
		Addr:"127.0.0.1:6379",
		Db:0,
		Password:"",
	}
	for _,fn :=range modoption{
		fn(&option)
	}
	return &OptionRedis{
		Id:id,
		Option:option,
	}
}
func (optionR *OptionRedis)ConnectInfo()  {
	fmt.Printf("addr:%s,db:%d,pass:%s\n", optionR.Option.Addr,optionR.Option.Db,optionR.Option.Password)
}

创建型Builder默认

  • 创建BuilderRedis结构体
  • 初始化BuilderRedis结构体NewBuilderRedis
  • 分别创建修改默认参数的方法
package redis

import (
	"fmt"
)

type BuilderRedis struct {
	Id 		 int
	Addr 	 string
	Db       int
	Password string
}

func NewBuilderRedis(id int) *BuilderRedis  {
	return &BuilderRedis{
		Id:id,
		Db:0,
		Addr:"127.0.0.1:6379",
		Password:"",
	}
}

func (builder *BuilderRedis)SetAddr(addr string) *BuilderRedis  {
	builder.Addr = addr
	return builder
}

func (builder *BuilderRedis)SetDb(db int) *BuilderRedis  {
	builder.Db = db
	return builder
}

func (builder *BuilderRedis)SetPwd(password string)*BuilderRedis  {
	builder.Password =password
	return builder
}

func (builder *BuilderRedis)ConnectInfo()  {
	fmt.Printf("addr:%s,db:%d,pass:%s\n", builder.Addr, builder.Db, builder.Password)
}

main包调用

package main

import "ParamDesginMode/redis"

func main()  {
	redis.NewBuilderRedis(1).SetAddr("127.0.0.1:63790").SetPwd("123455abc").ConnectInfo()
	redis.NewOptionRedis(2,redis.SetAddr("127.0.0.1:67390"),redis.SetPass("789123")).ConnectInfo()
}
// 输出
addr:127.0.0.1:63790,db:0,pass:123455abc
addr:127.0.0.1:67390,db:0,pass:789123

总结

Option模式和Builder模式都能构建容易维护的默认参数代码,但是从代码结构上看,个人觉得Builder 更易懂,更清晰,调用时使用类似链式写法调用,并不符合之前在Python语言类的默认参数函数调用方法,而Option符合Python语言中默认参数函数的调用方法,但代码和Builder比较起来相对复杂。