天天看點

Go 語言 設計模式-單例模式

單例模式

單例是一種建立型設計模式, 讓你能夠保證一個類隻有一個執行個體, 并提供一個通路該執行個體的全局節點。

單例擁有與全局變量相同的優缺點。 盡管它們非常有用, 但卻會破壞代碼的子產品化特性。

在某些其他上下文中, 你不能使用依賴于單例的類。 你也将必須使用單例類。 絕大多數情況下, 該限制會在建立單元測試時出現。

Go 語言 設計模式-單例模式

概念示例

通常而言, 單例執行個體會在結構體首次初始化時建立。 為了實作這一操作, 我們在結構體中定義一個 getInstance擷取執行個體方法。 該方法将負責建立和傳回單例執行個體。 建立後, 每次調用 getInstance時都會傳回相同的單例執行個體。

協程方面又有什麼需要注意的嗎? 每當多個協程想要通路執行個體時, 單例結構體就必須傳回相同的執行個體。 正因如此, 單例設計模式的實施工作很容易出錯。 下方的例子表示了建立單例的正确方式。

一些值得注意的地方:

最開始時會有 nil檢查, 確定 singleInstance單例執行個體在最開始時為空。 這是為了防止在每次調用 getInstance方法時都去執行消耗巨大的鎖定操作。 如果檢查不通過, 則就意味着 singleInstance字段已被填充。

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: 執行結果

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.      

繼續閱讀