Patron Observateur
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy — leçon 73 sur 91.
Le Patron Observateur (Observer Pattern) est un patron de conception comportemental qui établit une relation de un à plusieurs entre des objets. Lorsqu'un objet (le sujet) change d'état, tous ses dépendants (les observateurs) sont automatiquement notifiés et mis à jour.
Pensez à un abonnement à une newsletter. La newsletter est le sujet, et les abonnés sont les observateurs. Lorsqu'une nouvelle édition est publiée, tous les abonnés la reçoivent automatiquement sans que la newsletter n'ait besoin de connaître les détails de chaque abonné.
Voici une implémentation de base en PHP :
<?php
interface Observer {
public function update(string $message): void;
}
class Newsletter {
private array $subscribers = [];
public function subscribe(Observer $observer): void {
$this->subscribers[] = $observer;
}
public function publish(string $content): void {
foreach ($this->subscribers as $subscriber) {
$subscriber->update($content);
}
}
}
class EmailSubscriber implements Observer {
public function __construct(private string $email) {}
public function update(string $message): void {
echo "Sending to {$this->email}: $message\n";
}
}
$newsletter = new Newsletter();
$newsletter->subscribe(new EmailSubscriber("alice@example.com"));
$newsletter->subscribe(new EmailSubscriber("bob@example.com"));
$newsletter->publish("New article released!");
Sortie :
Sending to alice@example.com: New article released!
Sending to bob@example.com: New article released!Le patron découple le sujet de ses observateurs. La classe Newsletter n'a pas besoin de savoir si elle notifie des abonnés par e-mail, des abonnés par SMS ou des services de notification push. Elle appelle simplement update() sur tout ce qui implémente l'interface Observer. Cela rend l'ajout de nouveaux types d'observateurs sans effort, sans modifier le code existant.
Défi
FacileConstruisons un système d'alerte de prix d'actions en utilisant le modèle Observer (Observateur). Lorsqu'un prix d'action change, tous les investisseurs enregistrés doivent être informés automatiquement — une application concrète parfaite de ce modèle.
Vous organiserez votre code sur quatre fichiers :
Observer.php— Définissez une interfaceObserveravec une seule méthodeupdate(string $stockName, float $price): void. C'est le contrat que tous les observateurs doivent suivre pour recevoir des notifications.Investors.php— Incluez le fichier Observer et créez deux classes qui implémentent l'interface :EmailInvestor— Prend une adresse e-mail dans son constructeur (utilisez la promotion de constructeur). Sa méthodeupdate()affiche"Email to {$this->email}: {$stockName} is now \${$price}\n"SmsInvestor— Prend un numéro de téléphone dans son constructeur. Sa méthodeupdate()affiche"SMS to {$this->phone}: {$stockName} is now \${$price}\n"
Stock.php— Incluez le fichier Observer et créez une classeStockqui agit comme le sujet. Votre action doit :- Stocker le nom de l'action et le prix actuel (utilisez la promotion de constructeur pour le nom, initialisez le prix à
0.0) - Maintenir un tableau privé d'observateurs
- Avoir une méthode
subscribe(Observer $observer): voidpour ajouter des observateurs - Avoir une méthode
setPrice(float $price): voidqui met à jour le prix et notifie tous les observateurs
update()de chaque observateur avec le nom de l'action et le nouveau prix.- Stocker le nom de l'action et le prix actuel (utilisez la promotion de constructeur pour le nom, initialisez le prix à
main.php— Incluez les fichiers Investors et Stock. Vous recevrez trois entrées : un nom d'action, une adresse e-mail et un numéro de téléphone.Créez un
Stockavec le nom donné. Abonnez unEmailInvestoravec l'adresse e-mail et unSmsInvestoravec le numéro de téléphone.Fixez le prix de l'action à
150.50pour déclencher les notifications à tous les abonnés.
Le modèle Observer permet de garder votre classe Stock découplée des méthodes de notification spécifiques. Vous pourriez facilement ajouter un PushInvestor ou un SlackInvestor plus tard sans modifier la classe Stock du tout.
Aide-mémoire
Le Patron de conception Observateur (Observer Pattern) établit une relation de un à plusieurs où un sujet notifie automatiquement tous les observateurs lorsque son état change.
Composants clés :
- Interface Observateur — Définit le contrat pour les observateurs avec une méthode
update() - Sujet — Maintient une liste d'observateurs et les informe des changements d'état
- Observateurs concrets — Implémentent l'interface Observateur pour recevoir les notifications
Implémentation de base :
<?php
interface Observer {
public function update(string $message): void;
}
class Subject {
private array $observers = [];
public function subscribe(Observer $observer): void {
$this->observers[] = $observer;
}
public function notify(string $data): void {
foreach ($this->observers as $observer) {
$observer->update($data);
}
}
}
class ConcreteObserver implements Observer {
public function __construct(private string $name) {}
public function update(string $message): void {
echo "Notifying {$this->name}: $message\n";
}
}
$subject = new Subject();
$subject->subscribe(new ConcreteObserver("Observer1"));
$subject->subscribe(new ConcreteObserver("Observer2"));
$subject->notify("State changed!");
Avantages :
- Découple le sujet de ses observateurs
- Facile d'ajouter de nouveaux types d'observateurs sans modifier le code existant
- Prend en charge l'abonnement/désabonnement dynamique
Essayez vous-même
<?php
require_once 'Investors.php';
require_once 'Stock.php';
// Lire les entrées
$stockName = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));
// TODO: Créer une action (Stock) avec le nom donné
// TODO: Abonner un EmailInvestor avec l'adresse e-mail
// TODO: Abonner un SmsInvestor avec le numéro de téléphone
// TODO: Définir le prix de l'action à 150.50 pour déclencher les notifications
?>Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Les bases de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition de méthodeLe mot-clé finalClasses abstraitesRécapitulatif - Hiérarchie des employés7Encapsulation
Public, Protégé, PrivéModificateurs d'accès en détailGetters et SettersMasquage d'informationPromotion de constructeur (8.0)Récapitulatif - Système de gestion d'étudiants10Concepts avancés de la POO
Composition vs HéritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibers (PHP 8.1)Clonage d'objets : analyse approfondieGénérateurs et Itérateurs13Patrons de conception Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode ModèlePatron ÉtatPatron CompositePatron Repository2Espaces de noms et Autoloading
Introduction aux espaces de nomsLe mot-clé useStandard d'Autoloading PSR-4L'Autoloader ComposerRécapitulatif - Projet organisé5Interfaces et Contrats
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesInterface vs Classe AbstraiteType Hinting avec les InterfacesRécapitulatif - Calculateur de Formes8Méthodes magiques
Introduction aux méthodes magiques__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Clonage d'objets__serialize & __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d'instance vs Propriétés statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés readonly (PHP 8.1)Récapitulatif - Gestionnaire de compte bancaire6Polymorphisme
Retour sur la redéfinition de méthodePolymorphisme via les interfacesType Hinting et Types d'unionLiaison statique tardiveRécapitulatif - Processeur de paiement9Traits
Introduction aux TraitsUtilisation de plusieurs TraitsRésolution des conflits de TraitsMéthodes abstraites dans les TraitsTraits vs Héritage12Patrons de conception Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron ObservateurPatron Stratégie