Menu
Coddy logo textTech

Patrón Observer

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy. Lección 73 de 91.

El patrón Observer es un patrón de diseño de comportamiento que establece una relación de uno a muchos entre objetos. Cuando un objeto (el sujeto) cambia de estado, todas sus dependencias (los observadores) reciben una notificación y se actualizan automáticamente.

Piensa en una suscripción a un boletín. El boletín es el sujeto y los suscriptores son observadores. Cuando se publica una nueva edición, todos los suscriptores la reciben automáticamente sin que el boletín necesite conocer los detalles de cada suscriptor.

Aquí tienes una implementación básica 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!");

Salida:

Sending to alice@example.com: New article released!
Sending to bob@example.com: New article released!

El patrón desacopla el sujeto de sus observadores. La clase Newsletter no necesita saber si está notificando a suscriptores de correo electrónico, suscriptores de SMS o servicios de notificaciones push. Simplemente llama a update() en cualquier elemento que implemente la interfaz Observer. Esto facilita enormemente añadir nuevos tipos de observadores sin modificar el código existente.

challenge icon

Desafío

Fácil

Construyamos un sistema de alertas de precios de acciones usando el patrón Observer. Cuando el precio de una acción cambia, todos los inversores registrados deben recibir una notificación automáticamente: una aplicación perfecta de este patrón en el mundo real.

Organizarás tu código en cuatro archivos:

  • Observer.php: Define una interfaz Observer con un único método update(string $stockName, float $price): void. Este es el contrato que todos los observadores deben seguir para recibir notificaciones.
  • Investors.php: Incluye el archivo Observer y crea dos clases que implementen la interfaz:
    • EmailInvestor: Recibe una dirección de correo electrónico en su constructor (usa la promoción de constructor). Su método update() imprime "Email to [email]: [stockName] is now $[price]"
    • SmsInvestor: Recibe un número de teléfono en su constructor. Su método update() imprime "SMS to [phone]: [stockName] is now $[price]"
  • Stock.php: Incluye el archivo Observer y crea una clase Stock que actúe como sujeto. Tu acción debe:
    • Almacenar el nombre de la acción y el precio actual (usa la promoción de constructor para el nombre e inicializa el precio en 0.0)
    • Mantener un array privado de observadores
    • Tener un método subscribe(Observer $observer): void para añadir observadores
    • Tener un método setPrice(float $price): void que actualice el precio y notifique a todos los observadores
    Al notificar a los observadores, llama al método update() de cada observador con el nombre de la acción y el nuevo precio.
  • main.php: Incluye los archivos Investors y Stock. Recibirás tres entradas: el nombre de una acción, una dirección de correo electrónico y un número de teléfono.

    Crea un Stock con el nombre proporcionado. Suscribe un EmailInvestor con la dirección de correo electrónico y un SmsInvestor con el número de teléfono.

    Establece el precio de la acción en 150.50 para activar las notificaciones para todos los suscriptores.

El patrón Observer mantiene tu clase Stock desacoplada de los métodos de notificación específicos. Más adelante, podrías añadir fácilmente un PushInvestor o un SlackInvestor sin modificar en absoluto la clase Stock.

Pruébalo tú mismo

<?php
require_once 'Investors.php';
require_once 'Stock.php';

// Leer entradas
$stockName = trim(fgets(STDIN));
$email = trim(fgets(STDIN));
$phone = trim(fgets(STDIN));

// TODO: Crea un Stock con el nombre dado

// TODO: Suscribe un EmailInvestor con la dirección de correo electrónico

// TODO: Suscribe un SmsInvestor con el número de teléfono

// TODO: Establece el precio del stock a 150.50 para activar las notificaciones
?>
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 Programación Orientada a Objetos

Practica por tu cuenta: Compilador de PHP online