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);
   }
}