Patrones de diseño: Observer

Muy buenas a todos y todas, seguimos con los patrones de diseño, en esta ocasión, con uno de los más utilizados y conocidos a día de hoy, el patrón Observer.


Muy utilizado en Angular y programación reactiva.


Se compone de las siguientes clases: el sujeto, que es el objeto en observación, el observador y el cliente.


Observable: Es aquello que queremos observar, que será implementado mediante una colección de eventos o valores futuros. Un observable puede ser creado a partir de eventos de usuario derivados del uso de un formulario, una llamada HTTP, un almacén de datos, etc. Mediante el observable nos podemos suscribir a eventos que nos permiten hacer cosas cuando cambia lo que se esté observando.


Observer: Es el actor que se dedica a observar. Básicamente se implementa mediante una colección de funciones callback que nos permiten escuchar los eventos o valores emitidos por un observable. Las callbacks permitirán especificar código a ejecutar frente a un dato en el flujo, un error o el final del flujo.


Subject: es el emisor de eventos, que es capaz de crear el flujo de eventos cuando el observable sufre cambios. Esos eventos serán los que se consuman en los observers


Aquí podemos ver un diagrama de clases:


Lo primero será crear la interfaz Observer la cual va a ser implementada por todas las clases que van a ejercer la función de observador’.

public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}

Una vez tenemos esta clase y sus implementaciones, creamos la clase Subject, que va a obtener el estado, modificarlo y notificar a todos los observadores cuando se produzca un cambio.

public class Subject {
	
   private List<Observer> observers = new ArrayList<Observer>();
   private int state;

   public int getState() {
      return state;
   }

   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }

   public void attach(Observer observer){
      observers.add(observer);		
   }

   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   } 	
}

Como vemos, cada vez que se llama al método setState se notifica el cambio a todos los observadores. Ahora veamos la implementación de una de las clases que implementa Observer. El subject sería el sujeto que está siendo observado.

public class BinaryObserver extends Observer{

   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }
   @Override
   public void update() {
      System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); 
   }
}

Y por último, el uso de todo en la clase principal:

public class ObserverPatternDemo {
   public static void main(String[] args) {
      Subject subject = new Subject();
      new BinaryObserver(subject);
      System.out.println("First state change: 15");	
      subject.setState(15);
   }
}

Espero que te haya gustado esta pequeña explicación del patrón Observer, ya sabes dónde encontrarme en twitter: @juanmaperez_ nos vemos en la próxima :)

259 vistas

©2020 por Juanma Perez.