Go設計模式之單例模式講解和代碼示例
Go 單例模式講解和代碼示例.
單例是一種創(chuàng)建型設計模式, 讓你能夠保證一個類只有一個實例, 并提供一個訪問該實例的全局節(jié)點。
單例擁有與全局變量相同的優(yōu)缺點。 盡管它們非常有用, 但卻會破壞代碼的模塊化特性。
在某些其他上下文中, 你不能使用依賴于單例的類。 你也將必須使用單例類。 絕大多數情況下, 該限制會在創(chuàng)建單元測試時出現。
概念示例
通常而言, 單例實例會在結構體首次初始化時創(chuàng)建。 為了實現這一操作, 我們在結構體中定義一個 getInstance
獲取實例方法。 該方法將負責創(chuàng)建和返回單例實例。 創(chuàng)建后, 每次調用 getInstance
時都會返回相同的單例實例。
協程方面又有什么需要注意的嗎? 每當多個協程想要訪問實例時, 單例結構體就必須返回相同的實例。 正因如此, 單例設計模式的實施工作很容易出錯。 下方的例子表示了創(chuàng)建單例的正確方式。
一些值得注意的地方:
- 最開始時會有
nil
檢查, 確保singleInstance
單例實例在最開始時為空。 這是為了防止在每次調用getInstance
方法時都去執(zhí)行消耗巨大的鎖定操作。 如果檢查不通過, 則就意味著singleInstance
字段已被填充。 singleInstance
結構體將在鎖定期間創(chuàng)建。- 在獲取到鎖后還會有另一個
nil
檢查。 這是為了確保即便是有多個協程繞過了第一次檢查, 也只能有一個可以創(chuàng)建單例實例。 否則, 所有協程都會創(chuàng)建自己的單例結構體實例。
single.go: 單例
package main import ( "fmt" "sync" ) var lock = &sync.Mutex{} type single struct { } var singleInstance *single func getInstance() *single { if singleInstance == nil { lock.Lock() defer lock.Unlock() if singleInstance == nil { fmt.Println("Creating single instance now.") singleInstance = &single{} } else { fmt.Println("Single instance already created.") } } else { fmt.Println("Single instance already created.") } return singleInstance }
main.go: 客戶端代碼
package main import ( "fmt" ) func main() { for i := 0; i < 30; i++ { go getInstance() } // Scanln is similar to Scan, but stops scanning at a newline and // after the final item there must be a newline or EOF. fmt.Scanln() }
output.txt: 執(zhí)行結果
Creating single instance now.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
Single instance already created.
另一個例子
init
函數
我們可以在 init
函數中創(chuàng)建單例實例。 這僅適用于實例的早期初始化工作已經確定時。 init
函數僅會在包中的每個文件里調用一次, 所以我們可以確定其只會創(chuàng)建一個實例。
sync.Once
sync.Once
僅會執(zhí)行一次操作。 可查看下面的代碼:
syncOnce.go: 單例
package main import ( "fmt" "sync" ) var once sync.Once type single struct { } var singleInstance *single func getInstance() *single { if singleInstance == nil { once.Do( func() { fmt.Println("Creating single instance now.") singleInstance = &single{} }) } else { fmt.Println("Single instance already created.") } return singleInstance }
main.go: 客戶端代碼
package main import ( "fmt" ) func main() { for i := 0; i < 30; i++ { go getInstance() } // Scanln is similar to Scan, but stops scanning at a newline and // after the final item there must be a newline or EOF. fmt.Scanln() }
output.txt: 執(zhí)行結果
Creating single instance now.
Single instance already created.
Single instance already created.
到此這篇關于Go設計模式之單例模式講解和代碼示例的文章就介紹到這了,更多相關Go單例模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Go語言使用defer+recover解決panic導致程序崩潰的問題
如果協程出現了panic,就會造成程序的崩潰,這時可以在goroutine中使用recover來捕獲panic,進行處理,本文就詳細的介紹一下,感興趣的可以了解一下2021-09-09golang實現微信小程序商城后臺系統(tǒng)(moshopserver)
這篇文章主要介紹了golang實現微信小程序商城后臺系統(tǒng)(moshopserver),本文通過截圖實例代碼的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02GO接收GET/POST參數及發(fā)送GET/POST請求的實例詳解
這篇文章主要介紹了GO接收GET/POST參數及發(fā)送GET/POST請求,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12