DEV Community

Cover image for Le Design Pattern Observer : un système de notification puissant
TechniveK
TechniveK

Posted on

Le Design Pattern Observer : un système de notification puissant

Dans le développement de tes applications, tu auras souvent besoin que ton application puisse réagir à des événements de manière flexible. Par exemple, imaginons que tu souhaites notifier plusieurs systèmes lorsque certaines actions se produisent (comme l'inscription d'un utilisateur). C'est là que le Pattern Observer entre en jeu. Ce pattern te permet d'établir une relation entre des objets, afin que lorsque l'état de l'un change, tous les autres soient automatiquement informés et mis à jour.

Symfony implémente déjà efficacement ce pattern grâce à l'Event Dispatcher, ce qui le rend bien pratique et puissant à utiliser dans tes projets.

Qu'est-ce que le Pattern Observer ?

Le Pattern Observer permet de définir une relation entre le sujet observé et un ou plusieurs observateurs. Lorsqu'un changement d'état survient sur l'objet observé, tous les observateurs sont notifiés pour qu'ils puissent réagir en conséquence.

Voilà comment ça fonctionne :

  • 👨 Sujet (Observable) : L'objet principal qui change d'état.
  • 👀 Observateurs (Observers) : Les objets qui réagissent aux changements de l'observable.

Exemple

Imaginons que tu as un site où un utilisateur peut s'inscrire. À chaque inscription, tu veux envoyer un email de bienvenue, ajouter l'utilisateur à une liste de newsletters et informer un système d'analytics.

Plutôt que de tout coder de manière rigide au même endroit, tu peux déléguer ces tâches à différents observateurs qui seront informés dès que l'événement "utilisateur inscrit" est déclenché.

Implémentation du Pattern Observer dans Symfony

Dans Symfony, tu vas utiliser l'Event Dispatcher pour mettre en place le Pattern Observer. Ca va te permettre d'organiser le code proprement et de le rendre extensible sans modification de la logique de base.

Étape 1️⃣ : Déclarer l'Événement

On va commencer par créer un événement qui sera dispatché lorsqu'un utilisateur s'inscrit. Ce dernier contiendra les informations de l'utilisateur.

PHP UserRegisteredEvent class

Étape 2️⃣ : Dispatcher l'Événement

Maintenant, dans ton contrôleur ou service, tu vas dispatch cet événement quand un utilisateur s'inscrit.

Symfony RegistrationController

Étape 3️⃣ : Créer des Observateurs (Listeners)

Ensuite, tu vas devoir créer les observateurs, qui seront appelés à chaque fois que l'événement d'inscription est dispatché. Ici, tu as l'exemple où on envoie un email et on ajoute l'utilisateur à une liste de newsletters.

Observateur 1 : Envoyer un email de bienvenue

Symfony WelcomeEmailListener

Observateur 2 : Ajouter l'utilisateur à une liste de newsletters

Symfony NewsletterSubscriberListener

Étape 4️⃣ : Configuration des Observateurs

Tu dois maintenant enregistrer les listeners dans la configuration pour qu’ils écoutent l’événement user.registered.

Dans config/services.yaml, il faut ajouter les observateurs comme services :

Symfony services yml observers

ℹ️ Depuis la version 5.3 de Symfony, tu peux utiliser des attributs PHP pour configurer les services et les écouteurs d'événements (event listeners). C'est une approche plus moderne qui te permet de déclarer les événements directement dans les classes, au lieu d’utiliser le fichier services.yaml.
Tu peux donc utiliser l'attribut #[AsEventListener] directement sur la méthode de ton listener.

Je vais te montrer comment adapter les deux observateurs avec des attributs (donc plus besoin de config particulière dans config/services.yaml 😉 :

Observateur 1

Symfony WelcomeEmailListener

Observateur 2

Symfony NewsletterSubscriberListener

Petite explication

  • L'attribut #[AsEventListener] indique que la méthode est un listener pour un événement spécifique.
  • Le premier argument de l'attribut est le nom de l'événement que l'observateur écoute (UserRegisteredEvent::NAME).
  • Et enfin, le paramètre method précise la méthode de la classe qui sera exécutée lorsque l'événement sera déclenché (dans notre cas, onUserRegistered). 😄

Étape 5️⃣ : Tester l'implémentation

Lorsque tu enregistres un utilisateur avec le contrôleur RegistrationController, l'événement est dispatché et Symfony appelle automatiquement les observateurs correspondants. L'email est envoyé, et l'utilisateur est ajouté à la liste de newsletters sans que ces actions/logiques ne soient mélangées à ton code métier.

Pourquoi Utiliser le Pattern Observer ?

Parce que c'est un indispensable ! Il permettra à ton application d'être :

  1. Plus flexible : tu peux ajouter ou modifier des observateurs sans toucher à ton code principal. Il suffit d'ajouter un listener !
  2. Moins couplée : les différentes parties de ton appli ne sont pas étroitement liées. Par exemple, l'envoi d'emails et l'ajout à la newsletter ne sont pas codés directement dans le contrôleur d'inscription.
  3. Plus scalable : ce pattern permet de réagir facilement à des événements qui pourraient impliquer plusieurs systèmes ou services (notifications, analytics, envois, etc.).

Bonus : Le lien avec le DDD (Domain-Driven Design)

Le Pattern Observer trouve souvent sa place dans les architectures basées sur le DDD (Domain-Driven Design), où les événements sont des éléments clés (Domain Events). Ces événements permettent de faire réagir différentes parties du système, souvent en dehors du domaine principal. Mais ça, c’est une discussion pour un prochain article complet sur le DDD !

Top comments (0)