"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Modèle de conception singleton

Modèle de conception singleton

Publié le 2024-07-30
Parcourir:685

Singleton Design Pattern

Le modèle de conception Singleton est l'un des plus importants et des plus 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 discuterons de l'importance de Singleton, de la manière de l'implémenter dans Golang et des avantages qu'il apporte, en particulier dans les environnements simultanés.

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 cela.

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 la création et de l'accès à l'instance, facilitant ainsi 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.

Désavantages

  • 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 souhaitons 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 comporte 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 réellement que nous n'aurons qu'une seule instance en cours d'exécution, nous pouvons effectuer 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 à Golang.

Déclaration de sortie Cet article est reproduit sur : https://dev.to/rflpazini/singleton-design-pattern-1n51?1 En cas de violation, veuillez contacter [email protected] pour le supprimer.
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3