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

Le modèle Observateur est un modèle de conception comportemental utilisé pour établir une dépendance de un à plusieurs entre les objets. Plus précisément, lorsqu'un objet (appelé sujet ou observable) change, toutes ses dépendances (appelées observateurs) sont notifiées et mises à jour automatiquement. Ce modèle permet un couplage lâche entre les sujets et les observateurs, permettant ainsi le découplage et la flexibilité entre les objets.

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

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

  • Couplage lâche entre les sujets et les observateurs, où le sujet n'a pas besoin de connaître les détails spécifiques de l'implémentation des observateurs.
  • Ajout et retrait dynamiques d'observateurs, rendant le système plus flexible.
  • Respecte le principe ouvert-fermé entre les sujets et les observateurs, permettant une extension et une réutilisation indépendantes.
  • Peut établir une relation de dépendance de un à plusieurs, où un sujet peut avoir plusieurs observateurs.

3. Exemples d'applications pratiques du modèle Observateur

Le modèle Observateur a de nombreuses applications pratiques dans la vie réelle, telles que :

  • Mécanisme de gestion des événements dans les interfaces GUI, comme la gestion des actions lorsqu'un bouton est cliqué.
  • Envoi de cotations boursières en temps réel.
  • Notification des activités promotionnelles sur les plateformes de commerce électronique.

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

4.1 Diagramme de classe UML

Modèle Observateur en Golang

4.2 Introduction de l'exemple

Dans cet exemple, nous avons un sujet (Subject) et deux observateurs (ObserverA et ObserverB). Le sujet peut enregistrer, désenregistrer et notifier les observateurs.

4.3 Étapes de mise en oeuvre

4.3.1 Créer l'interface Sujet et la classe Sujet Concret

type Sujet interface {
    EnregistrerObservateur(observateur Observateur)
    SupprimerObservateur(observateur Observateur)
    NotifierObservateurs()
}

type SujetConcret struct {
    observateurs []Observateur
}

// Enregistrer l'objet observateur
func (sujet *SujetConcret) EnregistrerObservateur(observateur Observateur) {
    sujet.observateurs = append(sujet.observateurs, observateur)
}

// Supprimer l'objet observateur
func (sujet *SujetConcret) SupprimerObservateur(observateur Observateur) {
    for i, obs := range sujet.observateurs {
        if obs == observateur {
            sujet.observateurs = append(sujet.observateurs[:i], sujet.observateurs[i+1:]...)
            break
        }
    }
}

// Déclencher la notification de l'événement
func (sujet *SujetConcret) NotifierObservateurs() {
    for _, observateur := range sujet.observateurs {
        observateur.MettreAJour()
    }
}

4.3.2 Créer l'interface Observateur et les classes Observateur Concret

type Observateur interface {
    MettreAJour()
}

type ObservateurConcretA struct {}

func (observateur *ObservateurConcretA) MettreAJour() {
    fmt.Println("L'observateur A est notifié.")
}

type ObservateurConcretB struct {}

func (observateur *ObservateurConcretB) MettreAJour() {
    fmt.Println("L'observateur B est notifié.")
}

4.4 Démo du code d'exemple

func main() {
    sujet := &SujetConcret{}
    observateurA := &ObservateurConcretA{}
    observateurB := &ObservateurConcretB{}

    sujet.EnregistrerObservateur(observateurA)
    sujet.EnregistrerObservateur(observateurB)

    sujet.NotifierObservateurs()

    sujet.SupprimerObservateur(observateurA)

    sujet.NotifierObservateurs()
}

Résultat :

L'observateur A est notifié.
L'observateur B est notifié.
L'observateur B est notifié.

L'exemple de code ci-dessus illustre l'implémentation spécifique du modèle observateur. Le sujet (SujetConcret) a enregistré deux observateurs (ObservateurConcretA et ObservateurConcretB), puis a notifié ces deux observateurs. Ensuite, l'observateur A a été désenregistré du sujet et l'observateur restant B a été à nouveau notifié.