單例設計模式是軟體程式設計中最重要且最常用的設計模式之一。它確保類別在應用程式運行時只有一個實例,並提供對該實例的全域存取點。在這篇文章中,我們將討論 Singleton 的重要性、如何在 Golang 中實現它以及它帶來的好處,特別是在並發環境中。
單例是一種將類別的實例限制為單一實例的設計模式。它在需要單點控製或單一共享資源的情況下特別有用,例如:
我將列出一些關於 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。
以上是單例設計模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!