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
}