Patron Observer
Fait partie de la section Object Oriented Programming du Journey Python de Coddy — leçon 47 sur 64.
Le patron Observateur crée une relation de un à plusieurs dans laquelle un objet (sujet) notifie plusieurs objets (observateurs) lorsque son état change.
Voici une classe Subject simple qui gère des observateurs :
class Subject:
def __init__(self):
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def notify(self, message):
for observer in self._observers:
observer.update(message)Le sujet maintient une liste d'observateurs et peut tous les notifier simultanément.
Créez des classes d'observateurs simples :
class EmailNotifier:
def update(self, message):
print(f"Email sent: {message}")
class SMSNotifier:
def update(self, message):
print(f"SMS sent: {message}")Chaque observateur possède une méthode update qui est appelée lorsqu'il est notifié.
Utilisez le patron de conception observateur :
# Créer le sujet
news = Subject()
# Créer les observateurs
email = EmailNotifier()
sms = SMSNotifier()
# Ajouter les observateurs au sujet
news.add_observer(email)
news.add_observer(sms)
# Notifier tous les observateurs
news.notify("Breaking news: Python is awesome!")Créez un exemple pratique avec un suivi du cours des actions :
class Stock:
def __init__(self, symbol, price):
self.symbol = symbol
self._price = price
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def set_price(self, price):
self._price = price
self.notify()
def notify(self):
for observer in self._observers:
observer.update(self.symbol, self._price)
class Investor:
def __init__(self, name):
self.name = name
def update(self, symbol, price):
print(f"{self.name} notified: {symbol} is now ${price}")
# Use the stock tracker
apple_stock = Stock("AAPL", 150)
investor1 = Investor("Alice")
investor2 = Investor("Bob")
apple_stock.add_observer(investor1)
apple_stock.add_observer(investor2)
apple_stock.set_price(155) # Notifies all investorsSortie :
Email sent: Breaking news: Python is awesome!
SMS sent: Breaking news: Python is awesome!
Alice notified: AAPL is now $155
Bob notified: AAPL is now $155Point clé : Le patron de conception Observateur (Observer Pattern) permet à un objet de notifier automatiquement de nombreux autres objets lorsque quelque chose change. Le sujet maintient une liste d'observateurs et appelle leur méthode update au besoin. Ceci est utile pour les notifications, les systèmes d'événements et pour maintenir synchronisées plusieurs parties de votre application.
Défi
MoyenImplémentez le Pattern Observer en créant un système de surveillance météorologique. Vous devez créer deux classes dans les zones désignées du code.
Étape 1 : Créer la classe WeatherStation
Écrivez votre classe WeatherStation là où le commentaire l'indique. Cette classe doit :
- Hériter de la classe Subject (utilisez
class WeatherStation(Subject):) - S'initialiser avec :
- Appelez le constructeur parent en utilisant
super().__init__() - Définissez la température initiale à 0 en utilisant un attribut privé
self._temperature
- Appelez le constructeur parent en utilisant
- Implémenter
<strong>set_temperature(self, temperature)</strong>:- Mettre à jour l'attribut de température privé
- Appeler
self.notify(self._temperature)pour notifier tous les observateurs
- Implémenter
<strong>get_temperature(self)</strong>:- Retourner la valeur actuelle de la température
Étape 2 : Créer la classe WeatherDisplay
Écrivez votre classe WeatherDisplay là où le commentaire l'indique. Cette classe doit :
- Hériter de la classe Observer (utilisez
class WeatherDisplay(Observer):) - S'initialiser avec :
- Accepter un paramètre
name - Stocker le nom en tant que
self.name
- Accepter un paramètre
- Implémenter
<strong>update(self, temperature)</strong>:- Afficher le message de mise à jour de la température dans le format exact indiqué ci-dessous
Format du message :
Lorsqu'un affichage reçoit une mise à jour de température, il doit afficher exactement :
Display [name]: Current temperature is [temperature]CExemple d'utilisation :
# Create weather station and displays
station = WeatherStation()
phone_display = WeatherDisplay("Phone")
tablet_display = WeatherDisplay("Tablet")
# Attach displays to station
station.attach(phone_display)
station.attach(tablet_display)
# Update temperature - both displays will be notified
station.set_temperature(25.5)
# Output:
# Display Phone: Current temperature is 25.5C
# Display Tablet: Current temperature is 25.5CNotes importantes :
- Les méthodes
attach()etdetach()sont déjà implémentées dans la classe de base Subject - vous n'avez pas besoin de les implémenter ou de les appeler dans votre classe WeatherStation - Dans l'exemple d'utilisation ci-dessus,
station.attach(phone_display)est appelé par l'utilisateur de votre classe, pas à l'intérieur de votre implémentation de WeatherStation - Votre WeatherStation doit simplement appeler
self.notify()lorsque la température change - la classe de base Subject s'occupe du reste - Concentrez-vous sur l'implémentation des trois méthodes requises dans WeatherStation et des deux méthodes requises dans WeatherDisplay comme spécifié ci-dessus
Aide-mémoire
Le patron de conception Observateur (Observer Pattern) crée une relation de un à plusieurs où un objet (sujet) notifie plusieurs objets (observateurs) lorsque son état change.
Classe Subject de base qui gère les observateurs :
class Subject:
def __init__(self):
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def notify(self, message):
for observer in self._observers:
observer.update(message)Classes d'observateurs avec la méthode update :
class EmailNotifier:
def update(self, message):
print(f"Email sent: {message}")
class SMSNotifier:
def update(self, message):
print(f"SMS sent: {message}")Utilisation du patron observateur :
# Créer le sujet
news = Subject()
# Créer les observateurs
email = EmailNotifier()
sms = SMSNotifier()
# Ajouter les observateurs au sujet
news.add_observer(email)
news.add_observer(sms)
# Notifier tous les observateurs
news.notify("Breaking news: Python is awesome!")Exemple pratique avec un suivi du prix des actions :
class Stock:
def __init__(self, symbol, price):
self.symbol = symbol
self._price = price
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
def set_price(self, price):
self._price = price
self.notify()
def notify(self):
for observer in self._observers:
observer.update(self.symbol, self._price)
class Investor:
def __init__(self, name):
self.name = name
def update(self, symbol, price):
print(f"{self.name} notified: {symbol} is now ${price}")Le patron Observateur permet à un objet d'en notifier automatiquement plusieurs autres lorsque quelque chose change. Le sujet maintient une liste d'observateurs et appelle leur méthode update au besoin.
Essayez vous-même
class Subject:
def __init__(self):
self._observers = []
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
self._observers.remove(observer)
def notify(self, data):
for observer in self._observers:
observer.update(data)
class Observer:
def update(self, data):
pass
# Écrivez votre classe WeatherStation ici
# Écrivez votre classe WeatherDisplay ici
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Les fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe paramètre selfMéthodesAttributsMéthode constructeur (__init__)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLa fonction super()Redéfinition de méthodeHéritage multipleOrdre de résolution des méthodesRécapitulatif - Hiérarchie des employés7Méthodes spéciales
Introduction aux méthodes magiquesSurcharge d'opérateursMéthodes magiques de conteneurRécapitulatif - Liste personnalisée10Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy2Décorateurs
Introduction aux décorateursDécorateur de propriétéDécorateur de méthode statiqueDécorateur de méthode de classe5Polymorphisme
Retour sur la redéfinition de méthodeDuck TypingClasses et méthodes abstraitesConception d'interfacesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageMixinsMéthodes statiques et de classeDécorateurs de classeGestionnaires de contexte11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Propriétés de classe
Variables d'instance vs variables de classeDécorateurs de propriétéAttributs privésRécapitulatif - Gestionnaire de compte bancaire