SDSU inspiré de http://www.eli.sdsu.edu/courses/spring01/cs635/notes/observer/observer.html



References


Doc 10, Observer Slide # 2

Observer


Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically

Use the Observer pattern:






Structure





Collaborations






Implementation Java


Java API implements a framework for this pattern
Java
Observer Pattern
Interface Observer
Abstract Observer class
Observable class
Subject class



Class java.util.Observable


Observable object may have any number of Observers

Whenever the Observable instance changes,
it notifies all of its observers

Notification is done by calling the update() method on all observers.

Interface java.util.Observer


When implemented, this interface allows all classes to be observable by instances of class Observer



java.util.Observable Methods


addObserver(Observer)

Adds an observer to the observer list.


clearChanged()

Clears an observable change.


countObservers()

Counts the number of observers.


deleteObserver(Observer)

Deletes an observer from the observer list.


deleteObservers()

Deletes observers from the observer list.


hasChanged()

Returns a true boolean if an observable change has occurred.


notifyObservers()

Notifies all observers if an observable change occurs.


notifyObservers(Object)

Notifies all observers of the specified observable change which occurred.


setChanged()

Sets a flag to note an observable change.


Interface java.util.Observer

update

Called when observers in the observable list need to be updated



Doc 10, Observer Slide # 7

A Java Example


class Counter extends Observable 
   {
   public static final String INCREASE = "increase";
   public static final String DECREASE = "decrease";
   private int count = 0;
   private String label;
   
   public Counter( String label )   {   this.label = label; }
      
   public String label()         {  return label; }
   public int value()             {  return count; }
   public String toString()       {  return String.valueOf( count );}
      
   public void increase() 
      { 
      count++; 
      setChanged();
      notifyObservers( INCREASE ); 
      }
         
   public void decrease() 
      { 
      count--;
      setChanged();
      notifyObservers( DECREASE ); 
      }   
   }



Doc 10, Observer Slide # 8
class IncreaseDetector implements Observer
   {
   public void update( java.util.Observable whatChanged, 
                     java.lang.Object message)
      {
      if ( message.equals( Counter.INCREASE) ) 
         {
         Counter increased = (Counter) whatChanged;
         System.out.println( increased.label() + " changed to " + 
                              increased.value());
         }   
      }
   }



Doc 10, Observer Slide # 9
abstract class CounterButton extends Button
   {
   protected Counter count;
   
   public CounterButton( String buttonName, Counter count )
      {
      super( buttonName );
      this.count = count;
      }
      
   public boolean action( Event processNow, Object argument )
      {
      changeCounter();
      return true;
      }
   
   abstract protected void changeCounter();
   }


class IncreaseButton extends CounterButton
   {
   public IncreaseButton( Counter count )
      { 
      super( "Increase", count ); 
      }
   
   protected void changeCounter()
      { 
      count.increase(); 
      }   
   }

class DecreaseButton extends CounterButton
   {
   public DecreaseButton( Counter count )
      {
      super( "Decrease", count );
      }
      
   protected void changeCounter()
      { 
      count.decrease();
      }
   }


class ButtonController extends Frame
   {
   public ButtonController( Counter model, int x, int y, 
                        int width, int height )
      {
      setTitle( model.label() );
      reshape(x, y,  width, height );
      setLayout( new FlowLayout() );
      
      // buttons to change counter
      add( new IncreaseButton( model ));
      add( new DecreaseButton( model ));
      show();
      }
   }



Doc 10, Observer Slide # 11

Sample Program


class TestButton
   {
   public  static  void  main( String  args[] ){
      Counter x = new Counter( "x" );
      Counter y = new Counter( "y" );
   
      IncreaseDetector plus = new IncreaseDetector(  );
      x.addObserver( plus ); 
      y.addObserver( plus ); 
   
      new ButtonController( x,  30, 30, 150, 50 );
      new ButtonController( y,  30, 100, 150, 50 );
      }



Who Triggers the update?


   class Counter extends Observable 
      {      // some code removed
      public void increase() 
         { 
         count++; 
         setChanged();
         notifyObservers( INCREASE ); 
         }
      }


If there are several of changes at once, you may not want each change to trigger an update


It might be inefficient or cause too many screen updates


• Have clients call Notify at the right time

class Counter extends Observable 
      {   // some code removed
      public void increase()  {    count++;    }
      }
Counter pageHits = new Counter();
pageHits.increase();
pageHits.increase();
pageHits.increase();
pageHits.notifyObservers();



pull model - observer asks Subject what happened

class IncreaseDetector extends Counter implements Observer
   { // stuff not shown
      
   public void update( Observable whatChanged )
      {
      if ( whatChanged.didYouIncrease() )
         increase();
      }
   }


   class Counter extends Observable 
      {      // some code removed
      public void increase() 
         { 
         count++; 
         setChanged();
         notifyObservers( ); 
         }
      }