Menu
Coddy logo textTech

Patrón Observer

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 68 de 87.

El Patrón Observador 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 ello como una suscripción a un boletín: los suscriptores reciben actualizaciones cada vez que se publica contenido nuevo.

El patrón implica dos componentes principales: un sujeto que mantiene una lista de observadores y les notifica los cambios, y observadores que definen un método de actualización para responder a las notificaciones:

import java.util.ArrayList;
import java.util.List;

interface Observer {
    void update(String message);
}

class NewsPublisher {
    private List<Observer> subscribers = new ArrayList<>();
    
    public void subscribe(Observer observer) {
        subscribers.add(observer);
    }
    
    public void unsubscribe(Observer observer) {
        subscribers.remove(observer);
    }
    
    public void publish(String news) {
        for (Observer subscriber : subscribers) {
            subscriber.update(news);
        }
    }
}

class EmailSubscriber implements Observer {
    private String email;
    
    public EmailSubscriber(String email) {
        this.email = email;
    }
    
    public void update(String message) {
        System.out.println("Email to " + email + ": " + message);
    }
}

Cuando el editor publica noticias, todos los suscriptores reciben una notificación automáticamente:

NewsPublisher publisher = new NewsPublisher();
publisher.subscribe(new EmailSubscriber("alice@mail.com"));
publisher.subscribe(new EmailSubscriber("bob@mail.com"));

publisher.publish("Breaking news!");
// Salida:
// Email a alice@mail.com: ¡Noticias de última hora!
// Email a bob@mail.com: ¡Noticias de última hora!

El patrón Observer promueve un acoplamiento flexible: el sujeto no necesita conocer las clases concretas de sus observadores, solo que implementan la interfaz Observer. Esto facilita agregar nuevos tipos de observadores sin modificar el sujeto.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de alertas de precios de acciones usando el patrón Observer! Crearás un sistema en el que un marcador de cotizaciones notifica a varios inversores cada vez que cambia el precio de una acción, lo que permite que cada inversor reaccione a las actualizaciones de precios a su manera.

Organizarás tu código en cuatro archivos:

  • Observer.java: Define la interfaz Observer que implementarán todos los inversores. Debe declarar un único método update(String stockName, double price) que los observadores usan para recibir notificaciones sobre los cambios de precio.
  • StockTicker.java: Crea la clase sujeto que mantiene una lista de observadores y les notifica los cambios de precio. Tu StockTicker debe tener:

    Un campo String privado para el nombre de la acción (establecido mediante el constructor).

    Un campo double privado para el precio actual (inicialmente 0).

    Una lista privada para almacenar los observadores suscritos.

    Un método subscribe(Observer observer) que añade un observador a la lista.

    Un método unsubscribe(Observer observer) que elimina un observador de la lista.

    Un método setPrice(double price) que actualiza el precio y después notifica a todos los observadores llamando a su método update con el nombre de la acción y el nuevo precio.

  • Investors.java: Crea dos tipos diferentes de inversores que implementen la interfaz Observer:

    DayTrader: tiene un campo de nombre privado establecido mediante el constructor. Cuando recibe una actualización, imprime [name] received alert: [stockName] is now $[price] - Making quick trade!

    LongTermInvestor: tiene un campo de nombre privado establecido mediante el constructor. Cuando recibe una actualización, imprime [name] received alert: [stockName] is now $[price] - Holding steady.

    Formatea el precio con dos decimales.

  • Main.java: ¡Une todo tu sistema de observadores! Recibirás tres entradas: el nombre de la acción (String), la primera actualización del precio (double) y la segunda actualización del precio (double).

    Crea un StockTicker con el nombre de acción proporcionado. Crea un DayTrader llamado "Alice" y un LongTermInvestor llamado "Bob", y suscribe a ambos al marcador.

    Establece el precio en el primer valor de entrada (todos los observadores reciben una notificación). Después, cancela la suscripción de Alice. Finalmente, establece el precio en el segundo valor de entrada (esta vez solo Bob debe recibir una notificación).

Recibirás tres entradas en orden: nombre de la acción (String), primer precio (double), segundo precio (double).

Este desafío demuestra el poder del patrón Observer: StockTicker no sabe nada sobre los tipos específicos de inversores. Solo sabe que implementan Observer. Cuando cancelas la suscripción de Alice, deja de recibir actualizaciones mientras Bob continúa recibiendo notificaciones. Este acoplamiento flexible facilita añadir nuevos tipos de inversores sin cambiar el marcador.

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer entradas
        String stockName = scanner.nextLine();
        double firstPrice = scanner.nextDouble();
        double secondPrice = scanner.nextDouble();
        
        // TODO: Crea un StockTicker con el nombre de acción dado
        
        // TODO: Crea un DayTrader llamado "Alice"
        
        // TODO: Crea un LongTermInvestor llamado "Bob"
        
        // TODO: Suscribe tanto a Alice como a Bob al ticker
        
        // TODO: Establece el precio a firstPrice (ambos observadores son notificados)
        
        // TODO: Cancela la suscripción de Alice
        
        // TODO: Establece el precio a secondPrice (solo Bob es notificado)
        
        scanner.close();
    }
}
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 Java online