observer - Rose

Download Report

Transcript observer - Rose

OBSERVER
Doug Jeffries
Brian Marler
March 28, 2003
What is Observer
• Define a one-to-many dependency between
objects so that when one object changes
state, all its dependents are notified and
updated automatically. ~ GOF
• Keep objects consistent without
unnecessary coupling of the objects
• Subject sends notification to its observers
Example
• ClockTimer stores and maintains time
• DigitalClock and AnalogClock display
the time as kept by ClockTimer
• The two observers need to know when the
time changes, so that they can update their
displays
UML
Design Goals
• Data within an object should be highly
cohesive
– Belongs together, enforced consistency
• Data in different objects should be loosely
coupled
– Few consistency conditions
– Each class knows few other classes
• Observer can help us with this
Potential Problems
• Observing multiple subjects
– Thread-safety
– Distinguishing subjects
• Dangling subject references
More Examples
• Where have you seen Observers?
Common Uses for Observer
• Swing calls observers listeners
• User interface controls
– AncestorListener, MouseListener, ...
• Java beans context memberships
• Java beans vetoable changes
• I/O and Networking protocols
– Waiting for particular protocol states
Metsker Example
• Application to plot burn rate and thrust
• Swing JSlider control to adjust tpeak
• When slider changes, plots are updated
Challenge 9.1
• Complete these methods:
public JSlider slider()
{
if(slider == null)
{
slider = new JSlider();
sliderMax = slider.getMaximum();
sliderMin = slider.getMinimum();
slider.addChangeListener( ?? );
slider.setValue(slider.getMinimum());
}
return slider;
}
public void stateChanged(ChangeEvent e)
{
double val = slider.getValue();
double tp = (val - sliderMin) / (sliderMax - sliderMin);
burnPanel().?? ( ?? );
thrustPanel().?? ( ?? );
valueLabel().?? ( ?? );
}
Solution to Challenge 9.1
public JSlider slider()
{
if(slider == null)
{
slider = new JSlider();
sliderMax = slider.getMaximum();
sliderMin = slider.getMinimum();
slider.addChangeListener( this );
slider.setValue(slider.getMinimum());
}
return slider;
}
public void stateChanged(ChangeEvent e)
{
double val = slider.getValue();
double tp = (val - sliderMin) / (sliderMax - sliderMin);
burnPanel().setTPeak(tp);
thrustPanel().setTPeak(tp);
valueLabel().setText( Double.toString(tp) );
}
Challenge 9.2
• Provide a new class diagram showing a
design that lets each interested object
register for slider events. Be sure to account
for the label that shows the slider’s value.
Solution to Challenge 9.2
Challenge 9.3
• Write the complete code for
BallisticsLabel.java
Solution to Challenge 9.3
package com.oozinoz.applications;
import javax.swing.*;
import java.util.*;
import com.oozinoz.ballistics.Tpeak;
public class BallisticsLabel extends JLabel implements Observer
{
public BallisticsLabel(Tpeak tPeak)
{
tPeak.addObserver(this);
}
public void update(Observable o, Object arg)
{
setText( Double.toString(((Tpeak)o).getValue()) );
repaint();
}
}
Separation of Layers
• Model/View/Controller
Maintaining Observable Objects
• Observed objects must subclass Observable
– Problem: may already have parent class
– Solution: forward to Observable member
• Example from Java
– Component uses PropertyChangeSupport
– PropertyChangeListeners can then register
Thoughts?
Questions?