


















Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
The observer design pattern, which is a software design pattern that defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. An example of the observer pattern implementation in java and squeak, as well as the consequences and implementation issues of using this pattern.
Typology: Study notes
1 / 26
This page cannot be seen from the preview
Don't miss anything!



















CS 635 Advanced Object-Oriented Design & Programming Spring Semester, 2001 Doc 10 Observer Contents Observer ................................................................................................ Structure.............................................................................................. Collaborations...................................................................................... Java’s Implementation ......................................................................... A Java Example ................................................................................ Squeak Smalltalk Implementation...................................................... Squeak Example............................................................................. Consequences................................................................................... Implementation Issues....................................................................... Scaling the Pattern..........................................................................
References
Design Patterns: Elements of Reusable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, 1995, pp. 293-
The Design Patterns Smalltalk Companion, Alpert, Brown, Woolf, Addision-Wesley, 1998, pp. 305-
Java API
Squeak API
VisualWorks Smalltalk API
Copyright ©, All rights reserved. 2001 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA. OpenContent (http://www.opencontent.org/opl.shtml) license defines the copyright on this document.
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:
Collaborations
subject
observer A observer B
Update() GetState()
SetState()
Update()
subject observer A observer B Notify()
Update()
GetState() Update()
GetState()
SetState()
Java’s Implementation
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
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 ); } }
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()); } } }
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(); } }
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 ); }
Squeak Example
Model subclass: #Counter instanceVariableNames: 'count ' classVariableNames: '' poolDictionaries: '' category: 'Whitney-Examples'
Class Methods
new ^super new initialize
Instance Methods printOn: aStream aStream nextPutAll: count printString
decrease count := count - 1. self changed: #Decreased
increase count := count + 1. self changed: #Increased
initialize count := 0
Squeak Example - Continued
Object subclass: #IncreaseDetector instanceVariableNames: 'model ' classVariableNames: '' poolDictionaries: '' category: 'Whitney-Examples'
Class Methods
on: aCounter ^super new setModel: aCounter
Instance Methods
update: aSymbol aSymbol = #Increased ifTrue: [Transcript show: 'Count is now: ' , model printString; cr]
setModel: aCounter model := aCounter. aCounter addDependent: self
Consequences
Simple change in subject can cause numerous updates, which can be expensive or distracting
Subject can not perform any work until all observers are done
Implementation Issues
Mapping subjects(Observables) to observers
Use list in subject Use hash table
Observing more than one subject
If an observer has more than one subject how does it know which one changed?
Pass information in the update method
Dangling references to Deleted Subjects
Make sure Subject is self-consistent before Notification
Here is an example of the problem
class ComplexObservable extends Observable { Widget frontPart = new Widget(); Gadget internalPart = new Gadget();
public void trickyChange() { frontPart.widgetChange(); internalpart.anotherChange(); setChanged(); notifyObservers( ); } }
class MyBetterClass extends ComplexObservable { Gear backEnd = new Gear();
public void trickyChange() { super.trickyChange(); backEnd.yetAnotherChange(); setChanged(); notifyObservers( ); } }
A Template Method Solution to the Problem
class ComplexObservable extends Observable { Widget frontPart = new Widget(); Gadget internalPart = new Gadget();
public void trickyChange() { doThisChangeWithFactoryMethod(); setChanged(); notifyObservers( ); }
private void doThisChangeWithTemplateMethod() { frontPart.widgetChange(); internalpart.anotherChange(); } }
class MyBetterClass extends ComplexObservable { Gear backEnd = new Gear(); private void doThisChangeWithTemplateMethod() { backEnd.yetAnotherChange(); } }