本文主要是介绍选项(Option)设计模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
设计模式的出现,是为了解决编程中遇到的一些问题,现在有一个场景:
我们需要初始化一个服务的配置文件,比如是这样:
type Config struct {id intname stringip stringport string// other params ...
}
常见的初始化,有以下几种:
方式一:
func initConfig(id int, name, ip, port string) {conf.id = idconf.name = nameconf.ip = ipconf.port = port
}
这种方式,参数比较固定,比如我以后想扩展一些参数是很吃力的,而且,参数的位置也比较固定,就是说这个函数一旦开始被使用,参数位置就不能随意更改了,非常不灵活。
注意,可变参数(params ...interface{})也是一样,不能解决根本问题,参数位置还是固定的,而且函数内部还需要断言处理。
有些同学说,那我传个结构体不就行了吗,就不用考虑扩展参数和参数顺序问题了,于是就有了下一种方式:
方式二:
func initConfig(c Config) {conf.id = c.idconf.name = c.nameconf.ip = c.ipconf.port = c.port
}
这种方式确实解决了以上两个问题,但是也把所有配置全部暴露出去了,不但破坏了程序的封装性,而且,如果我想要一些默认的初始化,比如端口号默认8000,外部支持缺省配置,这又成问题了,于是又有了另一种方式:
方式三:
func setId(id int) {conf.id = id
}func setName(name string) {conf.name = name
}...
这种方式确实解决了以上问题,但是也产生了新的问题,随着参数的扩展,程序中的setXXX(或initXXX)方法也逐渐增加,而且,参数设置被分的很零散,不便于程序管理,再比如这时候想做个初始化统计,这种也是很繁琐,等等诸多问题。
=================
综上,那有没有一种方式,能够支持缺省配置,也能够在参数上随意的更换位置,初始化配置也不要调那么分散,能解决以上的这些问题呢?
于是,就有了option模式:
我这里先提供一个定义示例:
type Option func(opt *options)type options struct {id intname stringip stringport string// other params ...
}func WithId(id int) Option {return func(opt *options) {opt.id = id}
}func WithName(name string) Option {return func(opt *options) {opt.name = name}
}
然后是设置:
var conf = &options{port: "8000",
}func Parse(opt ...Option) {for _, o := range opt {o(conf)}
}
这就达到想要的效果了,需要扩展参数的时候,如果想对外暴露,就添加对应的With方法就可以了。
最后看一下使用:
func main() {Parse(WithName("testName"), WithId(1000))
}
使用也很简洁,每一个参数都是Option类型,参数数量和顺序都可以随意控制,达到了想要的效果!
这篇关于选项(Option)设计模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!