// patrón observador
import java.util.ArrayList;
import java.util.List;
class PruebaApp{
public static void main(String[] args) {
//crea un tema
MiTema miTema = new MiTema();
//crea observadores
Observador obj1 = new MiTemaSuscriptor("Obj1");
Observador obj2 = new MiTemaSuscriptor("Obj2");
Observador obj3 = new MiTemaSuscriptor("Obj3");
//registra observadores al tema
miTema.register(obj1);
miTema.register(obj2);
miTema.register(obj3);
obj1.setTema(miTema);
obj2.setTema(miTema);
obj3.setTema(miTema);
obj1.update(); //Verifica si algún update está disponible, basta uno.
miTema.postmensaje("Primer mensaje");
miTema.postmensaje("Segundo mensaje");
}
}
interface Tema {
//methods to registrar/unregister observadores
public void register(Observador obj);
public void unregister(Observador obj);
//method to notify observadores of change
public void notificarObservadores();
//method to get updates from tema
public Object getUpdate(Observador obj);
}
class MiTema implements Tema {
private List<Observador> observadores;
private String mensaje;
private boolean cambio;
private final Object MUTEX= new Object();
public MiTema(){
this.observadores=new ArrayList<>();
}
public void register(Observador obj) {
if(obj == null) throw new NullPointerException("Null Observador");
synchronized (MUTEX) {
if(!observadores.contains(obj)) observadores.add(obj);
}
}
public void unregister(Observador obj) {
synchronized (MUTEX) {observadores.remove(obj);}
}
public void notificarObservadores() {
List<Observador> observadoresLocales = null;
//synchronization is used to make sure any observer registered after messaje is received is not notified
synchronized (MUTEX) {
if (!cambio) return;
observadoresLocales = new ArrayList<>(this.observadores);
this.cambio=false;
}
for (Observador obj : observadoresLocales) {obj.update();}
}
public Object getUpdate(Observador obj) {return this.mensaje;}
//method to post mensaje to the topico
public void postmensaje(String mensaje){
System.out.println("Mensage publicado en el tema: " + mensaje);
this.mensaje = mensaje;
this.cambio = true;
notificarObservadores();
}
}
interface Observador {
public void update();
public void setTema(Tema tema);
}
class MiTemaSuscriptor implements Observador {
private String nombre;
private Tema tema;
public MiTemaSuscriptor(String nombre){this.nombre = nombre;}
public void update() {
String msg = (String) tema.getUpdate(this);
if(msg==null) System.out.println(nombre + ": No hay mensajes");
else System.out.println(nombre + ": Consumiendo un mensaje: " + msg);
}
public void setTema(Tema tema) {this.tema = tema;}
}