SDSU CS 683 Emerging Technologies
Spring Semester, 2003
Aspects & Observer Pattern
Previous    Lecture Notes Index    Next    
© 2003, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 06-Feb-03

Contents of Doc 7, Aspects & Observer Pattern


References

Design Pattern Implementation in Java and AspectJ, Hannemann & Kiczales, OOPSAL 2002, Seattle Washington Conference proceedings, Available at http://www.cs.ubc.ca/~jan/AODPs/

Design Patterns: Elements of Reusable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, 1995, pp. 293-303

Source Code for examples in Design Pattern Implementation in Java and AspectJ, See http://www.cs.ubc.ca/~jan/AODPs/ do download the examples


Doc 7, Aspects & Observer Pattern Slide # 2
Notice

This document contains source code written and copy written by Jan Hannemann and Gregor Kiczales. The code used is their Observer example from Design Pattern Implementation in Java and AspectJ, Hannemann & Kiczales, OOPSAL 2002, Seattle Washington Conference proceedings. The paper and source code is available at http://www.cs.ubc.ca/~jan/AODPs/.

The source code is under the Mozilla Public License Version 1.1. You may obtain a copy of the License at http://www.mozilla.org/MPL/.

The source code here as been modified to fit onto slides for display in a classroom. The edits include removing comments and some minor reformatting to conserve space.


Doc 7, Aspects & Observer Pattern Slide # 3
Coupling & Cohesion


Strength of interaction between objects in system



Degree to which the tasks performed by a single module are functionally related


Doc 7, Aspects & Observer Pattern Slide # 4

Observer Pattern

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:






Doc 7, Aspects & Observer Pattern Slide # 5

Structure





Doc 7, Aspects & Observer Pattern Slide # 6

Collaborations






Doc 7, Aspects & Observer Pattern Slide # 7
Simple ExampleReplace
Note example does not use legal Java

public class Subject {
   Window display;
   public void someMethod() {
      this.modifyMyStateSomeHow();
      display.addText( this.text() );
   }
}
With
public class Subject {
   ArrayList observers = new ArrayList();
   
   public void someMethod() {
      this.modifyMyStateSomeHow();
      changed();
   }
   
   private void changed() {
      Iterator needsUpdate = observers.iterator();
      while (needsUpdate.hasNext() )
         needsUpdate.next().update( this );
   }
}
   
public class SampleWindow {
   public void update(Object subject) {
      text = ((Subject) subject).getText();
      etc.
   }
}

Doc 7, Aspects & Observer Pattern Slide # 8

Consequences





Simple change in subject can cause numerous updates, which can be expensive or distracting



Subject cannot perform any work until all observers are done




Doc 7, Aspects & Observer Pattern Slide # 9

Point Example Without Aspects


Point that is to be displayed on the screen


Observer

public interface Observer {
    public void update(Subject s);
}

Subject

public interface Subject {
    
    public void attach(Observer o);
    public void detach(Observer o);
    public void notifyObservers();
}

Doc 7, Aspects & Observer Pattern Slide # 10

Point

import java.awt.Color;  
import java.util.HashSet;
import java.util.Iterator;
   
public class Point implements Subject { 
    
    private HashSet observers;
   
    private int x;
    private int y;
    private Color color;
    
    public Point(int x, int y, Color color) {
        this.x=x;
        this.y=y;
        this.color=color; 
        this.observers = new HashSet();
    }
    
    public int getX() { return x; }
   
    public int getY() { return y; }
   
    public void setX(int x) { 
        this.x=x; 
        notifyObservers();
    }


Doc 7, Aspects & Observer Pattern Slide # 11
Point Continued

    public void setY(int y) { 
        this.y=y; 
        notifyObservers();
    }
    public Color getColor() { return color; }
    public void setColor(Color color) { 
        this.color=color; 
        notifyObservers();
    }      
    
    public void attach(Observer o) {
        this.observers.add(o);
    }
    
    public void detach(Observer o) {
        this.observers.remove(o);
    }
    
    public void notifyObservers() {
        for (Iterator e = observers.iterator() ; e.hasNext() ;) {
            ((Observer)e.next()).update(this);
        }
    }
}

Doc 7, Aspects & Observer Pattern Slide # 12

Screen


import java.util.HashSet;
import java.util.Iterator;
 
public class Screen implements Subject, Observer {
         
    private HashSet observers;
    private String name;
    
    public Screen(String s) {
        this.name = s; 
        observers = new HashSet();
    }
    public void display (String s) {
       System.out.println(name + ": " + s);
       notifyObservers();
    }   
    public void attach(Observer o) {
        this.observers.add(o);
    }
    
    public void detach(Observer o) {
        this.observers.remove(o);
    }
    

Doc 7, Aspects & Observer Pattern Slide # 13
Screen Continued

    public void notifyObservers() {
        for (Iterator e = observers.iterator() ; e.hasNext() ;) {
            ((Observer)e.next()).update(this);
        }
    }
    public void update(Subject s) { 
        
        display("update received from a "+s.getClass().getName()+
         " object");
    }
}

Doc 7, Aspects & Observer Pattern Slide # 14

Sample Program


public static void main(String argv[]) {
   
   Point p = new Point(5, 5, Color.blue);
   
   System.out.println("Creating Screen s1,s2,s3,s4,s5 and Point p");
   
   Screen s1 = new Screen("s1");
   Screen s2 = new Screen("s2");
   
   Screen s3 = new Screen("s3");
   Screen s4 = new Screen("s4");
   
   Screen s5 = new Screen("s5");
   p.attach(s1); 
   p.attach(s2);
   
   p.attach(s3); 
   p.attach(s4);
   
   s2.attach(s5);
   s4.attach(s5);
   p.setColor(Color.red);
   p.setX(4); 
}

Doc 7, Aspects & Observer Pattern Slide # 15

Point Example Without Aspects


Point

import java.awt.Color;  
   
public class Point implements Subject { 
   
    private int x;
    private int y;
    private Color color;
    
    public Point(int x, int y, Color color) {
        this.x=x;
        this.y=y;
        this.color=color; 
    }
    
    public int getX() { return x; }
   
    public int getY() { return y; }
   
    public void setX(int x) {        this.x=x;    }

    public void setY(int y) {      this.y=y;    }
   
    public Color getColor() { return color; }
   
    public void setColor(Color color) {     this.color=color;   }      
    
}

Doc 7, Aspects & Observer Pattern Slide # 16

Screen


public class Screen {
    
    private String name;
    
    
    public Screen(String s) {
        this.name = s;
    }
     
    public void display (String s) {
        System.out.println(name + ": " + s);
    }
}

Doc 7, Aspects & Observer Pattern Slide # 17

ObserverProtocol

import java.util.WeakHashMap;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;
   
public abstract aspect ObserverProtocol {  
    protected interface Subject  { }    
    protected interface Observer { }
    private WeakHashMap perSubjectObservers;
    protected List getObservers(Subject s) { 
        if (perSubjectObservers == null) {
            perSubjectObservers = new WeakHashMap();
        }
        List observers = (List)perSubjectObservers.get(s);
        if ( observers == null ) {
            observers = new LinkedList();
            perSubjectObservers.put(s, observers);
        }
        return observers;
    }
    
    public void    addObserver(Subject s, Observer o) { 
        getObservers(s).add(o);    
    }
    

Doc 7, Aspects & Observer Pattern Slide # 18
ObserverProtocol Continued

    public void removeObserver(Subject s, Observer o) { 
        getObservers(s).remove(o); 
    }
    protected abstract pointcut subjectChange(Subject s);
    protected abstract void updateObserver(Subject s, Observer o);
    after(Subject s): subjectChange(s) {
        Iterator iter = getObservers(s).iterator();
        while ( iter.hasNext() ) {
            updateObserver(s, ((Observer)iter.next()));
        }
    } 
}


Doc 7, Aspects & Observer Pattern Slide # 19

ColorObserver

import java.awt.Color; 
  
public aspect ColorObserver extends ObserverProtocol{
  
 
  declare parents: Point  implements Subject; 
  declare parents: Screen implements Observer;
  protected pointcut subjectChange(Subject s): 
       call(void Point.setColor(Color)) && target(s);
  protected void updateObserver(Subject s, Observer o) {
      ((Screen)o).display("Screen updated because color changed.");
  }
}


Doc 7, Aspects & Observer Pattern Slide # 20

CoordinateObserver


public aspect CoordinateObserver extends ObserverProtocol{
 
  declare parents: Point  implements Subject;
   
  declare parents: Screen implements Observer;
 
  protected pointcut subjectChange(Subject s): 
    ( call(void Point.setX(int)) ||
      call(void Point.setY(int)) ) && target(s);
 
  protected void updateObserver(Subject s, Observer o) {
      ((Screen)o).display("Screen updated as coordinates changed.");
  }
}

Doc 7, Aspects & Observer Pattern Slide # 21

Sample Program


   public static void main(String argv[]) {
   
       Point p = new Point(5, 5, Color.blue);
       
       System.out.println("Creating Screen s1,s2,s3,s4,s5 and Point p");
       
       Screen s1 = new Screen("s1");
       Screen s2 = new Screen("s2");
       
       Screen s3 = new Screen("s3");
       Screen s4 = new Screen("s4");
       
       Screen s5 = new Screen("s5");
       ColorObserver.aspectOf().addObserver(p, s1);    
       ColorObserver.aspectOf().addObserver(p, s2);
       
       CoordinateObserver.aspectOf().addObserver(p, s3);   
       CoordinateObserver.aspectOf().addObserver(p, s4);
       
       ScreenObserver.aspectOf().addObserver(s2, s5);
       ScreenObserver.aspectOf().addObserver(s4, s5);
       p.setColor(Color.red);
       p.setX(4); 
       
    }
}

Doc 7, Aspects & Observer Pattern Slide # 22

Important Features


Point does not have any Observer/Subject code
All Observer/Subject code is localized in the aspects

ObserverProtocol can be used any Observer pattern instance
Subjects & Observers can be in multiple observer/subject relationships without their code becoming more complex
Subjects and observers can be used with or without the pattern

Copyright ©, All rights reserved.
2003 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.

Previous    visitors since 06-Feb-03    Next