<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
由於網上關於泛型使用的文章太多了,這裡就不聊怎麼使用泛型了,今天我們結合工廠方法+泛型方法來看一下泛型到底是如何在業務場景中使用的。本文涉及到的點如下:
話不多說,我們開始吧,具體泛型怎麼使用及語法,請自行查閱相關資料。
平時我們編寫結構體和方法的時候,一般是使用具體的型別:要麼是基本型別,要麼是自定義型別。但是如果要編寫可以應用於多種型別的程式碼的時候,那麼這種限制對程式的束縛就會比較大。
那麼我們想編出一些泛化的方法和介面,怎麼辦呢? 這個時候我們想到了介面,如果方法的引數是一個介面,而不是一個結構體,這樣對程式的限制就會放開了許多。因為任何實現該介面的結構體都可以作為該方法的介面引數,這樣就可以保證後面在新增其他同類功能的時候,只需實現這個介面就可以滿足需求了。
比如如下一個需求:
定義兩個手機品牌結構體華為,蘋果 ,並列印出各自品牌的名字。保證程式的擴充套件性,後面我們可能還要加入小米
import "fmt" //手機統一介面 type Phone interface { PrintBrand() } type HuaweiPhone struct { } func (hw *HuaweiPhone) PrintBrand() { fmt.Printf("品牌名字:華為") } type Iphone struct { } func (ip *Iphone) PrintBrand() { fmt.Printf("品牌名字:蘋果") } //統一列印方法 func PrintBrand(phone Phone) { phone.PrintBrand() } func main() { hw := HuaweiPhone{} ip := Iphone{} PrintBrand(ip) PrintBrand(hw) }
如上面程式碼,我們定義了兩個手機品牌的結構體,我們想列印各個手機的品牌名字,需要呼叫統一列印方法就可以了,如果後面新增其他品牌的話,我們只需要實現Phone
這個介面就可以,如下新增小米手機品牌:
type XiaomiPhone struct { } func (xm XiaomiPhone) PrintBrand() { fmt.Printf("品牌名字:小米") }
以上程式碼我們可以看到,通過介面也可以定義一些泛化的行為。
可是有時候,即便我們使用了介面,對程式的約束依然還是很強,因為一旦我們指明瞭具體的介面,就會要求我們必須使用特定的介面。而我們希望編寫更通用的程式碼,要使程式碼能夠應用於某種不具體的型別
,而不是具體的一個介面或者結構體。這個要怎麼辦呢?
比如,我們基於以上的需求繼續加需求
由於我們對接的品牌增大到20種,除了上面三種還有 魅族、三星、諾基亞、中興。。。。等等
這個時候我們基於當前的程式碼已經不能滿足,那麼我們想到了工廠設計模式,在工廠中用泛型來泛化所有的型別,我們通過傳入型別名字來列印出具體的品牌名。我們引入工廠模式繼續優化我們的程式碼,
如下:
var cache sync.Map //工廠方法 可以傳入任意的型別 func PhoneFactory[T any]() (t *T) { target := reflect.TypeOf(t) v, ok := cache.Load(t) if ok { return v.(*T) } v = new(T) v, _ = cache.LoadOrStore(target, v) return v.(*T) } func main() { PrintBrand(PhoneFactory[Iphone]()) PrintBrand(PhoneFactory[HuaweiPhone]()) PrintBrand(PhoneFactory[XiaomiPhone]()) }
程式碼中我們編寫了個工廠方法,泛型型別為 any, 接收任意的型別,在工廠中我們建立物件返回相應的型別並快取型別物件防止重複建立。這樣我們後面再加其他類別的時候可以通過這個工廠方法來統一的建立,我們還可以通過反射在建立前後根據業務需要做一些操作。
泛型的加入,無疑增加了程式碼的複雜度,那麼我們使用泛型的最佳時機是什麼時候呢?
Go 泛型主要設計者 Ian Lance Taylor 給出了簡要的泛型使用方針,當開發者發現自己多次編寫完全相同的程式碼,而這些副本之間的唯一區別僅在於使用了不同型別,這時候便可以考慮使用型別引數。換句話說,即開發者應避免使用型別引數,直到發現自己要多次編寫完全相同的程式碼。
比如說上面的業務,其實我們開始設計的時候設計到介面層面就可以了,如果一開始就引入工廠方法,其實這算是過度設計,我們設計一個功能的原則是,抓住上下文,適度設計,因為一旦我們投入了過多的精力到靈活設計上,勢必會影響本應該完成的需求。同時,過多的功能會引入更多潛在的問題,而修復問題也會耗費我們的時間和精力。而且在當前這個敏捷開發的時代,更是如此。
為了提高可閱讀性,以上程式碼都是以最簡單的方式呈現的,實際業務遠比這要複雜的多,這裡只是提供一種方向。
到此這篇關於Go泛型應用工廠方法及泛型使用的文章就介紹到這了,更多相關Go泛型應用內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45