Lab DesignPatterns 4
Lab DesignPatterns 4
Suppose we want to create an application that allows two people to watch on their mobile
phones two different types of presentations for the results of a student team in a competition.
Each student in the team will get a theory score and a practice score that will be used to
compute the average theory and practice scores of the team.
The results can be used by one type of displayer to show the current scores and by the other
type of displayer to show the trends of these scores.
A first try to implement this simple application is to use a class for the Score and two
classes, CurrentScoreDisplay and TrendDisplay, for the two displayers, as in the following
class diagram:
public scoreChanged ()
{
csd.update(int th, int pr);
td.update(int th, int pr);
}
}
}
}
If we try to expand the application with other displayers of the existing types or with new
types of displayers it will be difficult because code of the existing classes must be altered.
In this metaphor a publisher publishes a magazine and a subscriber automatically gets each
new edition of the magazine. The subscriber can also unsubscribe from the publisher and will get
no other magazine.
This metaphor is the basis for the OBSERVER design pattern.
Name:
OBSERVER
Intent:
Defines a one-to-many dependency between objects so that when one object changes
its state, all of its dependants are notified and updated automatically.
Structure:
Participants:
Subject (the publisher from the metaphor) publishes its state.
Observer (the subscriber from the metaphor) dependant, automatically notified and updated
when the state of the Subject changes.
Aplicability when:
- an abstraction has two aspects, one dependent on the other; encapsulating these aspects
in separate objects lets you vary and reuse them independently.
- a change to one object requires changing others, and you do not know how many objects
need to be changed.
- An object should be able to notify other objects without making assumptions about who
these objects are; in other words, you do not want these objects tightly coupled.
GOOD OO DESIGN PRACTICES:
P4. Strive for loosely coupled designs between objects that interact.
Advantages of OBSERVER:
1. Conforms to P4. Loose coupling characterizes the interaction between objects that have little
knowledge of each other.
For more flexibility we added another interface responsible to define display operation. It is not part
of the Observer pattern.
IMPLEMENTATION although Java (and other OO languages) support exists for Observer design
pattern, in a lot of cases is more flexible to implement your own structure.
And now let see how the pattern works. In order to test it we implement a class
Competition as follows:
s.setScore(7,8);
wait(2000);
s.setScore(5,9);
wait(2000);
s.setScore(10,9);
}
}
First an object of Score type is instantiated, to be the subject. Then two displayers
(CurrentScoreDisplay and TrendDisplay)are instantiated, and to their constructors a
reference to the Score object is given. This reference is used by the displayers to register as
observers to this subject.
Then the state of the Score object is changed from time to time, when calling the method
setScore() on it. Besides updating the values of the instance variables in the Score object, this
method will also call scoreChanged() which in turn calls notifyObservers().
Finally, the method notifyObservers() will call update() on all observeres registered to
the Score, so that all of them will update their values about the state of the Score and will display
this change correspondingly.
If we try now to expand the application with other displayers of the existing types we can
simply instantiate new objects of CurrentScoreDisplay type and/or of TrendDisplay type.
If we want to expand the application with new types of displayers it will be also simple. We
must first define separately the new type of displayer which will implement the Observer interface
similar to the other displayer types, and will implement the Display interface in its specific
manner. Then we can use it as previously described (as when expanding the application with
displayers of existing types).
Optional:
JAVA support for implementing OBSERVER design pattern.
Java offers support for implementing OBSERVER design pattern through the use of two
interfaces: java.util.Observer and java.util.Observable.
Interface java.util.Observer
public interface Observer
A class can implement the Observer interface when it wants to be informed of changes in observable objects.
See Also
o Observable
Method Index
Method Description
Methods
update
public void update(Observable o,
Object arg)
This method is called whenever the observed object is changed. An application calls an Ob-
servable object's notifyObservers method to have all the object's observers notified of the
change.
Parameters
o o - the observable object.
o arg - an argument passed to the notifyObservers method.
Class java.util.Observable
java.lang.Object
java.util.Observable
public class Observable
extends Object
This class represents an observable object, or "data" in the model-view paradigm. It can be subclassed to
represent an object that the application wants to have observed.
An observable object can have one or more observers. An observer may be any object that implements in-
terface Observer. After an observable instance changes, an application calling the Observable's notifyObservers
method causes all of its observers to be notified of the change by a call to their update method.
The order in which notifications will be delivered is unspecified. The default implementation provided in the
Observerable class will notify Observers in the order in which they registered interest, but subclasses may
change this order, use no guaranteed order, deliver notifications on separate threaads, or may guarantee
that their subclass follows this order, as they choose.
Note that this notification mechanism is has nothing to do with threads and is completely separate from the
wait and notify mechanism of class Object.
When an observable object is newly created, its set of observers is empty. Two observers are considered the
same if and only if the equals method returns true for them.
See Also
o notifyObservers
o notifyObservers
o Observer
o update
Constructor Index
Constructor Description
Method Index
Method Description
Adds an observer to the set of observers
void for this object, provided that it is not the
addObserver(Observer) same as some observer already in the set.
Indicates that this object has no longer
changed, or that it has already notified all
of its observers of its most recent change,
so that the hasChanged method will now
void clearChanged() return false.
Returns the number of observers of this
int countObservers() Observable object.
void
deleteObserver(Observ Deletes an observer from the set of
er) observers of this object.
Clears the observer list so that this object
void deleteObservers() no longer has any observers.
Constructors
Observable
public Observable()
Construct an Observable with zero Observers.
Methods
addObserver
public synchronized void addObserver(Observer o)
Adds an observer to the set of observers for this object, provided that it is not the same as
some observer already in the set. The order in which notifications will be delivered to mul-
tiple observers is not specified. See the class comment.
Parameters
o o - an observer to be added.
clearChanged
protected synchronized void clearChanged()
Indicates that this object has no longer changed, or that it has already notified all of its ob-
servers of its most recent change, so that the hasChanged method will now return false. This
method is called automatically by the notifyObservers methods.
See Also
o notifyObservers
o notifyObservers
countObservers
public synchronized int countObservers()
Returns the number of observers of this Observable object.
Returns
o the number of observers of this object.
deleteObserver
public synchronized void deleteObserver(Observer o)
Deletes an observer from the set of observers of this object.
Parameters
o o - the observer to be deleted.
deleteObservers
public synchronized void deleteObservers()
Clears the observer list so that this object no longer has any observers.
hasChanged
public synchronized boolean hasChanged()
Tests if this object has changed.
Returns
o true if and only if the setChanged method has been called more recently than
the clearChanged method on this object; false otherwise.
See Also
o clearChanged
o setChanged
notifyObservers
public void notifyObservers()
If this object has changed, as indicated by the hasChanged method, then notify all of its ob-
servers and then call the clearChanged method to indicate that this object has no longer
changed.
Each observer has its update method called with two arguments: this observable object and
null. In other words, this method is equivalent to:
notifyObservers(null)
See Also
o clearChanged
o hasChanged
o update
notifyObservers
public void notifyObservers(Object arg)
If this object has changed, as indicated by the hasChanged method, then notify all of its ob-
servers and then call the clearChanged method to indicate that this object has no longer
changed.
Each observer has its update method called with two arguments: this observable object and
the arg argument.
Parameters
o arg - any object.
See Also
o clearChanged
o hasChanged
o update
setChanged
protected synchronized void setChanged()
Marks this Observable object as having been changed; the hasChanged method will now return
true.