Maison  >  Article  >  développement back-end  >  Modèle de conception singleton

Modèle de conception singleton

王林
王林original
2024-07-18 13:46:47882parcourir

Singleton Design Pattern

Le modèle de conception Singleton est l'un des plus importants et fréquemment utilisés dans la programmation logicielle. Il garantit qu'une classe ne dispose que d'une seule instance pendant l'exécution de l'application et fournit un point d'accès global à cette instance. Dans cet article, nous aborderons l'importance de Singleton, comment l'implémenter dans Golang et les avantages qu'il apporte, notamment dans les environnements concurrents.

Qu’est-ce que Singleton ?

Singleton est un modèle de conception qui restreint l'instance d'une classe à une seule instance. Il est particulièrement utile dans les situations où un point de contrôle unique ou une seule ressource partagée est requis, telles que :

  • Gestionnaires de configuration, où les paramètres des applications doivent être centralisés.
  • Pools de connexions de base de données, où un nombre limité de connexions doivent être gérées efficacement.
  • Enregistreurs, où la cohérence des journaux est cruciale.

Pourquoi utiliser Singleton ?

Je vais énumérer quelques points sur l'implémentation de Pattern qui ont plus de sens et aussi pour montrer que tout n'est pas rose, certains des problèmes que nous pouvons avoir avec.

Avantages

  • Cohérence globale : garantit que tous les points de l'application utilisent la même instance, assurant ainsi la cohérence des données et des comportements.
  • Contrôle d'accès : centralise le contrôle de création et d'accès à l'instance, facilitant la maintenance et la gestion du cycle de vie de l'objet.
  • Efficacité des ressources : évite la création inutile de plusieurs instances, économisant ainsi la mémoire et les ressources de traitement.

Inconvénients

  • Difficulté des tests : les singletons peuvent rendre l'écriture de tests unitaires plus difficile car ils introduisent des états globaux qui doivent être gérés.
  • Couplage accru : une utilisation excessive de singletons peut conduire à un couplage plus étroit entre les composants, ce qui rend difficile la maintenance et l'évolution de l'application.

Implémentation d'un singleton

Pour implémenter un singleton, j'utiliserai Golang. Dans ce langage, nous devons accorder une attention particulière à la concurrence pour garantir qu'une seule instance est créée, même lorsque plusieurs goroutines tentent d'accéder à l'instance simultanément.

Pour rapprocher notre exemple du monde réel, créons un Logger pour notre application. Un enregistreur est un outil courant dans les applications qui doit être unique pour garantir la cohérence des journaux.

1 - Définir la structure

Tout d'abord, nous définissons la structure que nous voulons avoir pour une seule instance.

package logger

import (
    "fmt"
    "sync"
)

type Logger struct {}

var loggerInstance *Logger

2 - Implémentation de la fonction NewInstance

La fonction NewInstance est chargée de renvoyer l'instance unique de la structure Singleton. Nous utilisons un mutex pour garantir la sécurité dans les environnements concurrents, en mettant en œuvre un verrouillage à double vérification pour plus d'efficacité.

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 - Implémentation des types de journaux

Un outil de journalisation a toujours certains types de journaux, tels que Info pour afficher uniquement les informations, Erreur pour afficher les erreurs, etc. C'est un moyen de filtrer également le type d'informations que nous souhaitons afficher dans notre application.

Créons donc une méthode qui affichera notre journal avec le type Info. Pour ce faire, nous allons créer une fonction qui recevra notre message de journal et le formatera au format 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)
}

4 - Utiliser l'enregistreur

Et pour utiliser notre nouveau logger, nous allons l'instancier dans notre package principal et créer un journal pour voir comment fonctionne cette implémentation.

package main

import (
    "playground-go/pkg/logger"
)

func main() {
    log := logger.NewInstance()
    log.Info("This is an example of log")
}

Voici le résultat lorsque nous exécutons le programme :

Creating new logger
2024-07-03T19:34:57.609599Z - INFO: This is an example of log

Si nous voulons tester si NewInstance garantit vraiment que nous n'aurons qu'une seule instance en cours d'exécution, nous pouvons faire le test suivant.

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

Nos logs ont changé et nous pouvons désormais voir que nous avons bloqué la création d'une nouvelle 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

Conclusion

Le modèle Singleton est un outil puissant permettant de garantir qu'une seule instance d'une classe spécifique existe pendant l'exécution de l'application. Dans l'exemple du logger, nous avons vu comment ce modèle peut être appliqué pour garantir la cohérence des journaux dans l'ensemble de l'application.

J'espère que cela vous aidera à mieux comprendre Singleton en Golang.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Fusionner les listes triéesArticle suivant:Fusionner les listes triées