Patrón de Diseño Observer en Java:

El patrón Observer define una dependencia uno a muchos entre objetos, de modo que cuando un objeto cambia su estado, todos sus dependientes son notificados y actualizados automáticamente.

Ejemplo de Observer en Java:

Supongamos que tienes una interfaz Observador que define un método actualizar() que será llamado cuando el estado del sujeto cambie:

// Interfaz Observador
interface Observador {
    void actualizar(String mensaje);
}

Ahora, tienes una clase Sujeto que actúa como el sujeto observado. Los objetos interesados en cambios en el sujeto implementarán la interfaz Observador:

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

// Sujeto (Observado)
class Sujeto {
    private List<Observador> observadores = new ArrayList<>();
    private String mensaje;

    public void agregarObservador(Observador observador) {
        observadores.add(observador);
    }

    public void eliminarObservador(Observador observador) {
        observadores.remove(observador);
    }

    public void notificarObservadores() {
        for (Observador observador : observadores) {
            observador.actualizar(mensaje);
        }
    }

    public void establecerMensaje(String mensaje) {
        this.mensaje = mensaje;
        notificarObservadores();
    }
}

Ahora, puedes crear una implementación concreta de Observador llamada ObservadorConcreto:

// ObservadorConcreto
class ObservadorConcreto implements Observador {
    private String nombre;

    public ObservadorConcreto(String nombre) {
        this.nombre = nombre;
    }

    @Override
    public void actualizar(String mensaje) {
        System.out.println(nombre + " ha recibido el mensaje: " + mensaje);
    }
}

Finalmente, puedes usar estos componentes para demostrar el patrón Observer:

public class Principal {
    public static void main(String[] args) {
        // Crear un sujeto
        Sujeto sujeto = new Sujeto();

        // Crear observadores
        Observador observador1 = new ObservadorConcreto("Observador 1");
        Observador observador2 = new ObservadorConcreto("Observador 2");

        // Agregar observadores al sujeto
        sujeto.agregarObservador(observador1);
        sujeto.agregarObservador(observador2);

        // Cambiar el estado del sujeto
        sujeto.establecerMensaje("Nuevo mensaje para observadores");
    }
}

Cuándo usar el patrón Observer:

  1. Desacoplamiento entre Sujeto y Observadores:
    • Cuando deseas desacoplar el sujeto (objeto que experimenta cambios) de los observadores (objetos interesados en los cambios) para facilitar la extensión y la reutilización del código.
  2. Actualización Automática de Observadores:
    • Cuando necesitas que múltiples objetos reaccionen automáticamente a los cambios en el estado de otro objeto.
  3. Manejo de Eventos o Notificaciones:
    • Cuando trabajas con eventos o notificaciones y necesitas proporcionar una forma flexible de que otros objetos respondan a esos eventos.
  4. Implementación de Múltiples Observadores:
    • Cuando tienes varios objetos que deben mantenerse informados sobre los cambios en otro objeto.

El patrón Observer es especialmente útil en situaciones donde un objeto necesita informar a múltiples objetos sobre sus cambios de estado de manera eficiente y sin acoplar fuertemente a los observadores al sujeto. Proporciona una solución flexible para implementar el mecanismo de notificación y actualización.