Heim  >  Artikel  >  Backend-Entwicklung  >  Singleton-Entwurfsmuster

Singleton-Entwurfsmuster

王林
王林Original
2024-07-18 13:46:47877Durchsuche

Singleton Design Pattern

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 besprechen wir die Bedeutung von Singleton, wie man es in Golang implementiert und welche Vorteile es mit sich bringt, insbesondere in gleichzeitigen Umgebungen.

Was ist Singleton?

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:

  • Konfigurationsmanager, bei denen Anwendungseinstellungen zentralisiert werden müssen.
  • Datenbankverbindungspools, in denen eine begrenzte Anzahl von Verbindungen effizient verwaltet werden muss.
  • Logger, bei denen die Protokollkonsistenz entscheidend ist.

Warum Singleton verwenden?

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.

Vorteile

  • Globale Konsistenz: Stellt sicher, dass alle Punkte der Anwendung dieselbe Instanz verwenden, und sorgt so für Daten- und Verhaltenskonsistenz.
  • Zugriffskontrolle: Zentralisiert die Kontrolle über die Erstellung und den Zugriff auf die Instanz und erleichtert so die Wartung und Verwaltung des Lebenszyklus des Objekts.
  • Ressourceneffizienz: Vermeidet die unnötige Erstellung mehrerer Instanzen und spart so Speicher und Verarbeitungsressourcen.

Nachteile

  • Testschwierigkeit: Singletons können das Schreiben von Unit-Tests erschweren, da sie globale Zustände einführen, die verwaltet werden müssen.
  • Erhöhte Kopplung: Die übermäßige Verwendung von Singletons kann zu einer engeren Kopplung zwischen Komponenten führen, was die Wartung und Weiterentwicklung der Anwendung erschwert.

Implementierung eines Singletons

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.

1 - Definieren der Struktur

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

2 – Implementierung der NewInstance-Funktion

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 aus Effizienzgründen eine doppelt überprüfte Sperrung.

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
}

3 – Protokolltypen implementieren

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)
}

4 – Verwendung des Loggers

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")
}

Dies 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

Abschluss

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.

Das obige ist der detaillierte Inhalt vonSingleton-Entwurfsmuster. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn