Das Singleton-Entwurfsmuster ist eines der wichtigsten und am häufigsten verwendeten in der Softwareprogrammierung. Es stellt sicher, dass eine Klasse während der Anwendungslaufzeit nur eine einzige Instanz hat, und stellt einen globalen Zugriffspunkt auf diese Instanz bereit. In diesem Artikel werden wir die Bedeutung von Singleton diskutieren, wie man es in Golang implementiert und welche Vorteile es mit sich bringt, insbesondere in gleichzeitigen Umgebungen.
Singleton ist ein Entwurfsmuster, das die Instanz einer Klasse auf eine einzelne Instanz beschränkt. Dies ist besonders nützlich in Situationen, in denen ein einzelner Kontrollpunkt oder eine einzelne gemeinsam genutzte Ressource erforderlich ist, wie zum Beispiel:
Ich werde einige Punkte zur Implementierung von Pattern auflisten, die sinnvoller sind und auch zeigen, dass nicht alles rosig ist, sondern einige der Probleme, die wir damit haben können.
Um einen Singleton zu implementieren, verwende ich Golang. In dieser Sprache müssen wir besonders auf Parallelität achten, um sicherzustellen, dass nur eine Instanz erstellt wird, auch wenn mehrere Goroutinen gleichzeitig versuchen, auf die Instanz zuzugreifen.
Um unser Beispiel der realen Welt näher zu bringen, erstellen wir einen Logger für unsere Anwendung. Ein Logger ist ein gängiges Tool in Anwendungen, das eindeutig sein muss, um die Protokollkonsistenz sicherzustellen.
Zuerst definieren wir die Struktur, in der wir eine einzelne Instanz haben möchten.
package logger import ( "fmt" "sync" ) type Logger struct {} var loggerInstance *Logger
Die NewInstance-Funktion ist für die Rückgabe der einzelnen Instanz der Singleton-Struktur verantwortlich. Wir verwenden einen Mutex, um die Sicherheit in gleichzeitigen Umgebungen zu gewährleisten, und implementieren doppelt überprüfte Sperren für Effizienz.
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 }
Ein Protokolltool verfügt immer über einige Protokolltypen, z. B. „Info“, um nur die Informationen anzuzeigen, „Fehler“, um Fehler anzuzeigen usw. Auf diese Weise können Sie auch die Art der Informationen filtern, die wir in unserer Anwendung anzeigen möchten.
Erstellen wir also eine Methode, die unser Protokoll mit dem Info-Typ anzeigt. Dazu erstellen wir eine Funktion, die unsere Protokollnachricht empfängt und sie im INFO-Format formatiert.
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) }
Und um unseren neuen Logger zu verwenden, werden wir ihn in unserem Hauptpaket instanziieren und ein Protokoll erstellen, um zu sehen, wie diese Implementierung funktioniert.
package main import ( "playground-go/pkg/logger" ) func main() { log := logger.NewInstance() log.Info("This is an example of log") }
Das ist das Ergebnis, wenn wir das Programm ausführen:
Creating new logger 2024-07-03T19:34:57.609599Z - INFO: This is an example of log
Wenn wir testen möchten, ob NewInstance wirklich garantiert, dass nur eine Instanz ausgeführt wird, können wir den folgenden Test durchführen.
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") } }
Unsere Protokolle haben sich geändert und jetzt können wir sehen, dass wir die Erstellung einer neuen Instanz blockiert haben:
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
Das Singleton-Muster ist ein leistungsstarkes Tool, um sicherzustellen, dass während der Anwendungslaufzeit nur eine Instanz einer bestimmten Klasse vorhanden ist. Im Logger-Beispiel haben wir gesehen, wie dieses Muster angewendet werden kann, um die Protokollkonsistenz in der gesamten Anwendung sicherzustellen.
Ich hoffe, das hilft Ihnen, Singleton in Golang besser zu verstehen.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3