單例設計模式是軟體程式設計中最重要且最常用的設計模式之一。它確保類別在應用程式運行時只有一個實例,並提供對該實例的全域存取點。在這篇文章中,我們將討論 Singleton 的重要性,如何在 Golang 中實現它,以及它帶來的好處,特別是在並發環境中。
Singleton 是一種將類別的實例限制為單一實例的設計模式。它在需要單點控製或單一共享資源的情況下特別有用,例如:
我將列出一些關於 Pattern 實現的更有意義的觀點,同時也表明並非一切都是美好的,我們可能會遇到一些問題。
為了實作單例,我將使用 Golang。在這種語言中,我們必須特別注意並發性,以確保只創建一個實例,即使多個 goroutine 嘗試同時存取該實例也是如此。
為了讓我們的範例更接近現實世界,讓我們為我們的應用程式建立一個記錄器。記錄器是應用程式中常用的工具,需要唯一以確保日誌一致性。
首先,我們定義我們想要擁有單一實例的結構。
package logger import ( "fmt" "sync" ) type Logger struct {} var loggerInstance *Logger
NewInstance函數負責傳回Singleton結構的單一實例。我們使用互斥體來確保並發環境中的安全性,實現雙重檢查鎖定以提高效率。
package logger import ( "fmt" "sync" ) type Logger struct{} var logger *Logger var mtx = &sync.Mutex{} func NewInstance() *Logger { if logger == nil { mtx.Lock() defer mtx.Unlock() if logger == nil { fmt.Println("Creating new Logger") logger = &Logger{} } } else { fmt.Println("Logger already created") } return logger }
日誌工具總是有一些日誌類型,例如Info僅顯示訊息,Error顯示錯誤等等。這也是過濾我們想要在應用程式中顯示的資訊類型的一種方法。
因此,讓我們建立一個方法來顯示 Info 類型的日誌。為此,我們將建立一個函數來接收日誌訊息並將其格式化為 INFO 格式。
package logger import ( "fmt" "sync" "time" ) const ( INFO string = "INFO" ) type Logger struct{} var logger *Logger var mtx = &sync.Mutex{} func NewInstance() *Logger { if logger == nil { mtx.Lock() defer mtx.Unlock() if logger == nil { fmt.Println("Creating new logger") logger = &Logger{} } } else { fmt.Println("Logger already created") } return logger } func (l *Logger) Info(message string) { fmt.Printf("%s - %s: %s\n", time.Now().UTC().Format(time.RFC3339Nano), INFO, message) }
要使用我們的新記錄器,我們將在主套件中實例化它並建立日誌以查看此實作的工作原理。
package main import ( "playground-go/pkg/logger" ) func main() { log := logger.NewInstance() log.Info("This is an example of log") }
這是我們運行程式的結果:
Creating new logger 2024-07-03T19:34:57.609599Z - INFO: This is an example of log
如果我們想測試NewInstance是否真的保證只有一個實例在運行,我們可以進行以下測試。
package main import ( "fmt" "playground-go/pkg/logger" ) func main() { log := logger.NewInstance() log.Info("This is an example of log") log2 := logger.NewInstance() log2.Info("This is another example of log") if log == log2 { fmt.Println("same instance") } else { fmt.Println("different instance") } }
我們的日誌已更改,現在我們可以看到我們阻止了新實例的建立:
Creating new logger 2024-07-03T19:45:19.603783Z - INFO: This is an example of log Logger already created 2024-07-03T19:45:19.603793Z - INFO: This is another example of log same instance
單例模式是一種強大的工具,可確保應用程式運行時僅存在特定類別的一個實例。在記錄器範例中,我們了解如何應用此模式來確保整個應用程式中的日誌一致性。
希望這可以幫助您更好地理解 Golang 中的 Singleton。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3