go micro 原始碼閱讀-Options [Functional O
解決的問題
如果想提供一個具有可選引數的方法,那麼在其他語言中很簡單使用預設值就好了。然而在Go中不支援預設值的做法,退而求其次那麼使用函式過載好了,接著就會發現Go中同樣不支援函式過載,那麼我使用不同的函式名好了。。。。(程式碼估計很醜,並且不容易辨析)
** Go 不支援預設值引數和函式過載的原因 **
Method dispatch is simplified if it doesn't need to do type matching as well. Experience with other languages told us that having a variety of methods with the same name but different signatures was occasionally useful but that it could also be confusing and fragile in practice. Matching only by name and requiring consistency in the types was a major simplifying decision in Go's type system.
Regarding operator overloading, it seems more a convenience than an absolute requirement. Again, things are simpler without it
如果不需要做型別匹配的話那麼函式分發的處理就會簡單。並且具有同樣函式名的函式卻有不同的型別(增加了程式碼的理解難度,比如你在讀一份程式碼的時候,看到一個函式呼叫,然而這個函式呼叫卻有不同的過載或者不同數量的呼叫引數的話,那麼頭腦裡就要維護這個函式的多個版本,始終不如只存在一個版本理解上來的容易),並且保持函式名和函式型別的一致,可以是Go的型別系統的處理更加簡單。
解決方案
以上對Go不支援可選引數和函式過載的原因進行了說明,可是實際的程式設計中確實有這種模型的需要,如何解決這種問題呢。及如何使用不變的介面,實行可變的構造行為(可變----》 不變的轉換)
構造者模式
本身這個一個物件的夠著的問題,可以從構造模式的方向進行考慮,顯然透過Builder(構造者模式)可以解決這個問題。
可變引數
func Fun(arg ...int)的方式,可是這種方式可變引數的型別只能是統一中型別,那麼如果用interface,當然可以,只是函式體內充滿了型別斷言,對函式本身的邏輯造成了很大的干擾。(職能單一原則)
Functional Options Pattern
與Builder模式類似,變---》不變的轉換,找到變動的元素,然後固定他。把變的東西透過特定的設計歸一它,把變動的引數型別,歸約為不變的函式型別,類似於變換到同型別的可變引數(函式型別)。(及變動的邏輯,只以一種方式存在)
比如說我想製作一杯咖啡,(糖,牛奶,咖啡粉,鹽,酒,冰淇淋,蜂蜜。。。。。)這些原料應該是可以選擇新增的。那麼:一杯 二/,就可以隨意新增自己喜歡的原料了。
type func CoffeeOption (Opts *CoffeeOptions)type CoffeeOptions struct{ sugar int milk int cofferPowder int ... }type Coffee struct{ opts *CoffeeOptions }func CoffeeSugar(sugar int)CoffeeOption{ return func(opts *ConffeeOptions){ opts.sugar = sugar } }func CoffeeMilk(milk int)CoffeeOption{ return func(opts *ConffeeOptions){ opts.milk = milk } }func newDefaultCoffeeOptions()*CoffeeOptions{ return &CoffeeOptions{ sugar:2, milk:5, coffeePowder:100, ..... } }func NewCoffee(opts ...CoffeeOption)*Coffer{ defaultOptions = newDefaultCoffeeOptions() for _,opt := range opts{ opt(defaultOptions) } return &Coffee{ opts:defaultOptions, } }
應用
在go-micro中你可以看到很多functional options pattern的應用,基本每個micro元件都使用了這種方式進行構造。
在grpc中同樣很多地方也使用了這種方式。
作者:inclee
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2249/viewspace-2805013/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 三、GO 程式設計模式:FUNCTIONAL OPTIONSGo程式設計設計模式Function
- go 中 select 原始碼閱讀Go原始碼
- [轉]Golang Functional Options PatternGolangFunction
- opentracing-go原始碼閱讀一Go原始碼
- 【原始碼閱讀】AndPermission原始碼閱讀原始碼
- Jaeger tchannel-go —— readme原始碼閱讀Go原始碼
- Jaeger tchannel-go原始碼閱讀——PeerGo原始碼
- basictracer-go原始碼閱讀二——SpanGo原始碼
- go-micro之原始碼剖析: RegistryGo原始碼
- basictracer-go原始碼閱讀——event&propagationGo原始碼
- basictracer-go原始碼閱讀——SpanRecorder與wireGo原始碼
- basictracer-go原始碼閱讀——examples(完結)Go原始碼
- 【原始碼閱讀】Glide原始碼閱讀之with方法(一)原始碼IDE
- 【原始碼閱讀】Glide原始碼閱讀之into方法(三)原始碼IDE
- Micro原始碼系列 - Go-Micro服務是如何註冊的原始碼Go
- opentracing-go原始碼閱讀——資訊攜帶Go原始碼
- 第 27 期 go mod 原始碼閱讀 part 2Go原始碼
- 【原始碼閱讀】Glide原始碼閱讀之load方法(二)原始碼IDE
- Go排程器系列(4)原始碼閱讀與探索Go原始碼
- ReactorKit原始碼閱讀React原始碼
- Vollery原始碼閱讀(—)原始碼
- NGINX原始碼閱讀Nginx原始碼
- ThreadLocal原始碼閱讀thread原始碼
- 原始碼閱讀-HashMap原始碼HashMap
- Runtime 原始碼閱讀原始碼
- RunLoop 原始碼閱讀OOP原始碼
- AmplifyImpostors原始碼閱讀原始碼
- stack原始碼閱讀原始碼
- CountDownLatch原始碼閱讀CountDownLatch原始碼
- fuzz原始碼閱讀原始碼
- HashMap 原始碼閱讀HashMap原始碼
- delta原始碼閱讀原始碼
- AQS原始碼閱讀AQS原始碼
- Mux 原始碼閱讀UX原始碼
- ConcurrentHashMap原始碼閱讀HashMap原始碼
- HashMap原始碼閱讀HashMap原始碼
- PostgreSQL 原始碼解讀(3)- 如何閱讀原始碼SQL原始碼
- opentracing-go原始碼閱讀——Log儲存(完結篇)Go原始碼