本文主要介紹了Go語言中函式式選項模式及該設計模式在實際編程中的應用,
為什么需要函式式選項模式?
最近看go-micro/options.go原始碼的時候,發現了一段關于服務注冊的代碼如下:
type Options struct {
Broker broker.Broker
Cmd cmd.Cmd
Client client.Client
Server server.Server
Registry registry.Registry
Transport transport.Transport
// Before and After funcs
BeforeStart []func() error
BeforeStop []func() error
AfterStart []func() error
AfterStop []func() error
// Other options for implementations of the interface
// can be stored in a context
Context context.Context
}
func newOptions(opts ...Option) Options {
opt := Options{
Broker: broker.DefaultBroker,
Cmd: cmd.DefaultCmd,
Client: client.DefaultClient,
Server: server.DefaultServer,
Registry: registry.DefaultRegistry,
Transport: transport.DefaultTransport,
Context: context.Background(),
}
for _, o := range opts {
o(&opt)
}
return opt
}
當時呢,也不是很明白newOptions這個建構式為什么要這么寫,但是后面在微信群里看到有人也再發類似的代碼問為什么要這么寫,后來在群里討論的時候才知道了這是一種設計模式–函式式選項模式,
可能大家看到現在也不是很明白我說的問題到底是什么,我把它簡單提煉一下,
我們現在有一個結構體,定義如下:
type Option struct {
A string
B string
C int
}
現在我們需要為其撰寫一個建構式,我們可能會寫成下面這種方式:
func newOption(a, b string, c int) *Option {
return &Option{
A: a,
B: b,
C: c,
}
}
上面的代碼很好理解,也是我們一直在寫的,有什么問題嗎?
我們現在來思考以下兩個問題:
- 我們可能需要為Option的欄位指定默認值
- Option的欄位成員可能會發生變更
選項模式
我們先定義一個OptionFunc的函式型別
type OptionFunc func(*Option)
然后利用閉包為每個欄位撰寫一個設定值的With函式:
func WithA(a string) OptionFunc {
return func(o *Option) {
o.A = a
}
}
func WithB(b string) OptionFunc {
return func(o *Option) {
o.B = b
}
}
func WithC(c int) OptionFunc {
return func(o *Option) {
o.C = c
}
}
然后,我們定義一個默認的Option如下:
var (
defaultOption = &Option{
A: "A",
B: "B",
C: 100,
}
)
最后撰寫我們新版的建構式如下:
func newOption2(opts ...OptionFunc) (opt *Option) {
opt = defaultOption
for _, o := range opts {
o(opt)
}
return
}
測驗一下:
func main() {
x := newOption("nazha", "小王子", 10)
fmt.Println(x)
x = newOption2()
fmt.Println(x)
x = newOption2(
WithA("沙河娜扎"),
WithC(250),
)
fmt.Println(x)
}
輸出:
&{nazha 小王子 10}
&{A B 100}
&{沙河娜扎 B 250}
這樣一個使用函式式選項設計模式的建構式就實作了,這樣默認值也有了,以后再要為Option添加新的欄位也不會影響之前的代碼,
推薦閱讀:
Go 函式式選項模式
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/47200.html
標籤:Go
上一篇:Go語言中的單例模式(翻譯)
下一篇:LeetCode
