Menu
Coddy logo textTech

Patrón Observer

Parte de la sección Object Oriented Programming del Journey de Python de Coddy — lección 47 de 64.

El patrón Observer crea una relación de uno a muchos en la que un objeto (sujeto) notifica a múltiples objetos (observadores) cuando su estado cambia.

Aquí hay una clase Subject sencilla que gestiona observadores:

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)

El sujeto mantiene una lista de observadores y puede notificarlos a todos a la vez.

Crea clases observadoras simples:

class EmailNotifier:
    def update(self, message):
        print(f"Email sent: {message}")

class SMSNotifier:
    def update(self, message):
        print(f"SMS sent: {message}")

Cada observador tiene un método update que se llama cuando se le notifica.

Usa el patrón observer:

# Crear el sujeto
news = Subject()

# Crear los observadores
email = EmailNotifier()
sms = SMSNotifier()

# Añadir observadores al sujeto
news.add_observer(email)
news.add_observer(sms)

# Notificar a todos los observadores
news.notify("Breaking news: Python is awesome!")

Crea un ejemplo práctico con un rastreador de precios de acciones:

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 investors

Salida:

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 $155

Punto clave: El Patrón Observer permite que un objeto notifique a muchos otros automáticamente cuando algo cambia. El sujeto mantiene una lista de observadores y llama a su método update cuando es necesario. Esto es útil para notificaciones, sistemas de eventos y para mantener sincronizadas múltiples partes de su aplicación.

challenge icon

Desafío

Intermedio

Implementa el Patrón Observer creando un sistema de monitoreo meteorológico. Debes crear dos clases en las áreas designadas del código.

Paso 1: Crear la clase WeatherStation

Escribe tu clase WeatherStation donde el comentario lo indica. Esta clase debe:

  • Heredar de la clase Subject (usa class WeatherStation(Subject):)
  • Inicializarse con:
    • Llamar al constructor padre usando super().__init__()
    • Establecer la temperatura inicial a 0 usando un atributo privado self._temperature
  • Implementar <strong>set_temperature(self, temperature)</strong>:
    • Actualizar el atributo de temperatura privado
    • Llamar a self.notify(self._temperature) para notificar a todos los observadores
  • Implementar <strong>get_temperature(self)</strong>:
    • Retornar el valor de la temperatura actual

Paso 2: Crear la clase WeatherDisplay

Escribe tu clase WeatherDisplay donde el comentario lo indica. Esta clase debe:

  • Heredar de la clase Observer (usa class WeatherDisplay(Observer):)
  • Inicializarse con:
    • Aceptar un parámetro name
    • Almacenar el nombre como self.name
  • Implementar <strong>update(self, temperature)</strong>:
    • Imprimir el mensaje de actualización de temperatura en el formato exacto que se muestra a continuación

Formato del Mensaje:

Cuando una pantalla recibe una actualización de temperatura, debe imprimir exactamente:

Display [name]: Current temperature is [temperature]C

Ejemplo de Uso:

# 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.5C

Notas Importantes:

  • Los métodos attach() y detach() ya están implementados en la clase base Subject; no necesitas implementarlos ni llamarlos dentro de tu clase WeatherStation
  • En el ejemplo de uso anterior, station.attach(phone_display) es llamado por el usuario de tu clase, no dentro de tu implementación de WeatherStation
  • Tu WeatherStation solo necesita llamar a self.notify() cuando la temperatura cambia; la clase base Subject se encarga del resto
  • Enfócate en implementar los tres métodos requeridos en WeatherStation y los dos métodos requeridos en WeatherDisplay como se especificó anteriormente

Hoja de referencia

El Patrón Observer crea una relación de uno a muchos donde un objeto (sujeto) notifica a múltiples objetos (observadores) cuando su estado cambia.

Clase Subject básica que gestiona observadores:

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)

Clases Observer con el método update:

class EmailNotifier:
    def update(self, message):
        print(f"Email sent: {message}")

class SMSNotifier:
    def update(self, message):
        print(f"SMS sent: {message}")

Uso del patrón observer:

# Crear sujeto
news = Subject()

# Crear observadores
email = EmailNotifier()
sms = SMSNotifier()

# Añadir observadores al sujeto
news.add_observer(email)
news.add_observer(sms)

# Notificar a todos los observadores
news.notify("Breaking news: Python is awesome!")

Ejemplo práctico con un rastreador de precios de acciones:

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}")

El Patrón Observer permite que un objeto notifique a muchos otros automáticamente cuando algo cambia. El sujeto mantiene una lista de observadores y llama a su método update cuando es necesario.

Pruébalo tú mismo

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

# Escribe tu clase WeatherStation aquí

# Escribe tu clase WeatherDisplay aquí

quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Object Oriented Programming