1. Qu'est-ce que le modèle Singleton

Le modèle Singleton est un modèle de conception de création qui garantit qu'une classe a une seule instance et fournit un point d'accès global à cette instance pour la récupération. Le modèle singleton est couramment utilisé dans des scénarios où des ressources doivent être partagées ou que l'accès à une instance spécifique doit être contrôlé.

2. Caractéristiques et avantages du modèle Singleton

Le modèle Singleton présente les caractéristiques et avantages suivants :

  • Garantit qu'une seule instance de la classe est créée
  • Fournit un point d'accès global pour que le code externe obtienne l'instance
  • Évite la création répétée d'instances, économisant ainsi les ressources du système

3. Scénarios d'application du modèle Singleton

Le modèle Singleton est adapté aux scénarios d'application suivants :

  • Enregistreurs : garantir qu'il n'y ait qu'un seul enregistreur pour l'ensemble du système afin d'éviter les enregistrements en double.
  • Pool de connexions de base de données : dans des environnements à haute concurrence, l'utilisation du modèle Singleton permet d'éviter la création et la destruction fréquentes des connexions de base de données.

4. Implémentation du modèle Singleton en Golang

En Golang, il existe différentes manières d'implémenter le modèle Singleton. Voici deux méthodes d'implémentation communes.

4.1. Implémentation à l'aide d'une initialisation paresseuse et d'une initialisation hâtive

L'initialisation paresseuse crée l'instance objet lors de sa première utilisation, tandis que l'initialisation hâtive crée l'instance objet au démarrage du programme.

// Implémentation du modèle Singleton avec initialisation paresseuse
package singleton

type Singleton struct {
}

var instance *Singleton

func GetInstance() *Singleton {
    if instance == nil {
        instance = &Singleton{}
    }
    return instance
}

// Implémentation du modèle Singleton avec initialisation hâtive
package singleton

type Singleton struct {
}

var instance *Singleton = &Singleton{}

func GetInstance() *Singleton {
    return instance
}

4.2. Problèmes de sécurité liés au modèle Singleton dans les threads

La méthode d'implémentation à initialisation paresseuse mentionnée ci-dessus peut présenter des problèmes dans un environnement multi-thread, car plusieurs threads peuvent simultanément entrer dans la condition if instance == nil, entraînant la création de plusieurs instances.

4.3. Implémentation du modèle Singleton thread-safe à l'aide de sync.Once

L'utilisation de sync.Once garantit qu'une seule goroutine exécute le code d'initialisation, résolvant ainsi le problème de sécurité lié aux threads.

// Implémentation du modèle Singleton thread-safe à l'aide de sync.Once
package singleton

import (
    "sync"
)

type Singleton struct {
}

var instance *Singleton
var once sync.Once

func GetInstance() *Singleton {
    once.Do(func() {
        instance = &Singleton{}
    })
    return instance
}

4.4. Implémentation du modèle Singleton initialisation paresseuse thread-safe à l'aide de sync.Mutex

Une autre manière d'implémenter un modèle Singleton à initialisation paresseuse thread-safe est d'utiliser sync.Mutex pour verrouiller et garantir qu'une seule goroutine exécute l'opération d'initialisation.

// Implémentation du modèle Singleton initialisation paresseuse thread-safe à l'aide de sync.Mutex
package singleton

import (
    "sync"
)

type Singleton struct {
}

var instance *Singleton
var mu sync.Mutex

func GetInstance() *Singleton {
    if instance == nil {
        mu.Lock()
        defer mu.Unlock()
        if instance == nil {
            instance = &Singleton{}
        }
    }
    return instance
}