Sablonul de proiectare Observer
Descriere
Sablonul observer este utilizat atunci cand se doreste ca unul sau mai multe obiecte sa fie notificate cu privire la schimbarea starii unui alt obiect. Sablonul implementeaza un mecanism de inregistrare a obiectelor interesate de schimbarea starii obiectului tinta si un mecanism de schimbare a starii obiectului tinta. In momentul schimbarii starii obiectului se poate transmite si o informatie suplimentara catre observatori prin intermediul unui obiect event.
Java standard implementeaza sablonul Observer prin intermediul claselor Observer si Observable localizate in pachetul java.util. Primul exemplu de mai jos prezinta o implementare proprie a acestui sablon. Al doilea exemplu implementare utilizeaza clasele Observer si Observable din pachetul java.
Diagrama UML
Exemple
Exemplul 1
import java.util.ArrayList; import java.util.List; class Observable { private List<Observer> observers = new ArrayList<Observer>(); public void changeState(Object event) { notifyAllObservers(event); } public void register(Observer observer){ observers.add(observer); } private void notifyAllObservers(Object event){ for (Observer observer : observers) { observer.update(event); } } } interface Observer { public abstract void update(Object event); } //usage example class Alarm extends Observable{ void startAlarm(){ System.out.println("Alarm has been started!"); this.changeState("START"); } void stopAlarm(){ System.out.print("Alarm has been stopped!"); this.changeState("STOP"); } } class AlarmMonitor implements Observer{ @Override public void update(Object event) { System.out.println("Alarm status has changed!"); System.out.println("Received event: Event class:"+event.getClass()+":"+event.toString()); } } public class Client { public static void main(String[] args) throws InterruptedException{ Alarm fireAlarm = new Alarm(); AlarmMonitor monitor = new AlarmMonitor(); fireAlarm.register(monitor); fireAlarm.startAlarm(); Thread.sleep(500); fireAlarm.stopAlarm(); } }
Rezultatul executiei programului:
Alarm has been started! Alarm status has changed! Received event: Event class:class java.lang.String:START Alarm has been stopped!Alarm status has changed! Received event: Event class:class java.lang.String:STOP
Exemplul 2
Utilizarea claselor Observable si Observer din java standard.
import java.util.Observable; import java.util.Observer; class ObservedObject extends Observable { private String watchedValue; public ObservedObject(String value) { watchedValue = value; } public void setValue(String value) { // if value has changed notify observers if(!watchedValue.equals(value)) { System.out.println("Value changed to new value: "+value); watchedValue = value; // mark as value changed setChanged(); // trigger notification notifyObservers(value); } } } public class ObservableDemo implements Observer { public static void main(String[] args) { // create watched and watcher objects ObservedObject watched = new ObservedObject("Original Value"); // watcher object listens to object change ObservableDemo watcher = new ObservableDemo(); // trigger value change watched.setValue("New Value"); // add observer to the watched object watched.addObserver(watcher); // trigger value change watched.setValue("Latest Value"); } public void update(Observable obj, Object arg) { System.out.println("Update called with Arguments: "+arg); } }