/** * 使用匿名函数实现操作封装 * 将匿名函数作为 map 的键值,通过命令行参数动态调用匿名函数 * 运行命令 go run src/hh/main.go --skill=fly */
顺晟科技
2021-06-16 10:27:05
189
为什么我需要功能选项模式?
最近看了go-micro/options.go源代码,发现一个关于服务注册的代码如下:
类型选项结构{
经纪人经纪人。经纪人
Cmd cmd。煤矿管理局
客户端客户端。客户
服务器服务器。计算机网络服务器
注册表注册表。登记处
运输运输。运输
//前后函数
BeforeStart []func()错误
BeforeStop []func()错误
AfterStart []func()错误
AfterStop []func()错误
//接口实现的其他选项
//可以存储在上下文中
语境语境。语境
}
新选项功能(选项.选项)选项{
opt :=选项{
Broker:代理。DefaultBroker,
Cmd: cmd。DefaultCmd,
Client:客户端。默认客户端,
Server:服务器。默认服务器,
注册表:注册表。默认注册表,
运输:运输。默认传输,
Context:上下文。背景(),
}
for _,o :=range opts {
o(选择)
}
返回选项
}
当时不太明白为什么构造函数newOptions要这么写,后来看到微信群里有人发类似的代码问为什么要这么写。后来在小组里讨论的时候,才知道这是一种设计模式——功能选项模式。
可能大家都不太明白我现在说的是什么问题。我就简单提炼一下。
我们现在有一个如下定义的结构:
选项类型结构{
一根绳子
b弦
C int
}
现在我们需要为它编写一个构造函数,我们可以用下面的方式编写它:
函数新选项(a,b字符串,c整数)*选项{
返回选项{
A: a,
B: b,
C: c,
}
}
上面的代码很好理解,我们一直在写。有问题吗?
现在让我们思考以下两个问题:
我们可能需要为选项字段指定默认值
选项的字段成员可能会更改
选项模式
我们首先定义一个可选函数的函数类型
键入选项函数(*选项)
然后使用闭包来编写一个为每个字段设置值的With函数:
func WithA(字符串)OptionFunc {
返回功能(o *选项){
o.A=a
}
}
func WithB(b字符串)OptionFunc {
返回功能(o *选项){
o.B=b
}
}
func WICh(c int)option func {
返回功能(o *选项){
o.C=c
}
}
然后,我们将默认选项定义如下:
var(
默认选项=选项{
A: 'A ',
B: 'B ',
C: 100,
}
)
最后,我们编写新的构造函数如下:
功能新选项2(选项.OptionFunc) (opt *Option) {
opt=defaultOption
for _,o :=range opts {
o(选择)
}
返回
}
测试一下:
func main() {
X :=newOption('哪吒','小王子',10)
fmt。Println(x)
x=新选项2()
fmt。Println(x)
x=新选项2(
与('沙河哪吒'),
带(250),
)
fmt。Println(x)
}
输出:
{哪吒小王子10}
{ a100 }
沙河哪吒B 250
实现了一个使用功能选项设计模式的构造器。这样就有了默认值,以后为Option添加新字段也不会影响之前的代码。
16
2021-06
16
2021-06
16
2021-06
16
2021-06
16
2021-06
16
2021-06