observer pattern - cp.eng.chula.ac.thchate/2110443/design-patter.pdf · observer pattern 22. new...
TRANSCRIPT
Design Pattern
Observer Pattern
Weather Data
Weather Data
display
2Observer Pattern
TestDisplaypackage nonpattern;
import javax.swing.*;
public class TextDisplay extends JPanel {
JLabel label;
public TextDisplay() {
label = new JLabel(" ");
add(label);
}
public void update(int temp) {
label.setText(""+temp);
validate();
}
}
3Observer Pattern
SliderDisplay
package nonpattern;
import javax.swing.*;
public class SliderDisplay extends JPanel {
JSlider slider;
public SliderDisplay() {
slider = new JSlider();
add(slider);
}
public void update(int value) {
slider.setValue(value);
validate();
}
}
4Observer Pattern
WeatherData
package nonpattern;
public class WeatherData {
int temperature;
TextDisplay text;
SliderDisplay slider;
public void addDisplay(TextDisplay display) {
this.text = display;
}
public void addDisplay(SliderDisplay display) {
this.slider = display;
}
5Observer Pattern
WeatherData
public void measurementChanged() {
temperature = getTemperature();
text.update(temperature);
slider.update(temperature);
}
public int getTemperature() {
return (int)(Math.random()*100);
}
}
6Observer Pattern
Main Application
public class MainApp extends JFrame {
TextDisplay text;
// add new display here
SliderDisplay slider;
public static void main(String[] args) {
final WeatherData weather = new WeatherData();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainApp(weather).initGUI();
}
});
7Observer Pattern
Main Application
while(true) {
try {
Thread.sleep(1000);
weather.measurementChanged();
} catch (InterruptedException ex) {
Logger.getLogger(
MainApp.class.getName()).log(
Level.SEVERE, null, ex);
}
}
}
8Observer Pattern
Main Application
public MainApp(WeatherData w) {
super("Non Pattern Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// add display here
text = new TextDisplay();
w.addDisplay(text);
// init new display
slider = new SliderDisplay();
w.addDisplay(slider);
}
9Observer Pattern
Main Application
public void initGUI() {
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(text, BorderLayout.LINE_END);
// add new display to frame
cp.add(slider,BorderLayout.PAGE_END);
pack();
setVisible(true);
}
}
10Observer Pattern
New Display to Be Added
• WeatherData
– add new display field
– add new methods to set the display field
– add new display update statement
• Need to change the program!
11Observer Pattern
Observer Pattern
Weather Data
new value
Observer Objects
12Observer Pattern
Observer Pattern
Weather Data
Observer Objects
13Observer Pattern
register/subscribe
Observer Pattern
Weather Data
Observer Objects
14Observer Pattern
Observer Pattern
Weather Data
new value
Observer Objects
15Observer Pattern
Observer Pattern
Weather Data
Observer Objects
16Observer Pattern
remove/unsubscribe
Observer Pattern
Weather Data
Observer Objects
17Observer Pattern
Observer Pattern
Weather Data
new value
Observer Objects
18Observer Pattern
Observer Pattern
• one-to-many dependency between objects
• when object changes state
• all dependencies are notified and update automatically.
Observer Pattern 19
Class Diagram
Observer Pattern 20
+update()
«interface»
Observer
+registerObserver()
+removeObserver()
+notifyObserver()
«interface»
Subject
-registerObserver
-removeObserver
-notifyObserver
-getState
-setState
«implementation class»
ConcreteSubject +update()
ConcreteObserver
Advantages
• Subjects (data) only implements a certain interface (Observer interface)
• new observers can be add at any time
• never have to modify subject (data) when new observer is added
• reuse subject(data) and observer
• change to subject will not affect on observer and vice versa
Observer Pattern 21
Interfaces
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
public interface Observer {
public void update(int data);
}
public interface DisplayElement {
public void display();
}
Observer Pattern 22
New WeatherData
public class WeatherData implements Subject {
private ArrayList observers;
private int temperature;
public WeatherData() {
observers = new ArrayList();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
Observer Pattern 23
new WeatherDatapublic void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer)observers.get(i);
observer.update(temperature);
}
}
public void measurementChanged() {
temperature = getTemperature();
notifyObservers();
}
public void setMeasurements(int temperature) {
this.temperature = temperature;
measurementChanged();
}
public int getTemperature() {
return (int)(Math.random()*100);
}
}
Observer Pattern 24
New TextDisplay
public class TextDisplay extends JPanelimplements Observer, DisplayElement {
int temperature;WeatherData weather;JLabel label;
public TextDisplay(WeatherData weather) {this.weather = weather;weather.registerObserver(this);label = new JLabel(" ");add(label);
}
public void update(int data) {this.temperature = data;display();
}
public void display() {label.setText(""+temperature);validate();
}}
Observer Pattern 25
Java Build-in Observer Pattern
Observer Pattern 26
+addObserver()
+deleteObserver()
+notifyObservers()
+setChanged()
Observable
+getTemperature()
WeatherData
+update()
+display()
TextDisplay
+update()
+display()
SliderDisplay
+update()
+display()
ProgressDisplay
+update()
«interface»
Observer
observers
subject
How it work? (1)
• Implement the Observer interface (java.util.Observer)– addObserver()
– deleteObserver()
• To send notification– call setChanged() to change the state of the object
– call notifyObservers() or notifyObservers(Object dataObj)
• Observers receive notifications– update(Observable o, Object dataObj)
Observer Pattern 27
data object
How it work? (2)
setChanged() {
changed = true;
}
notifyObservers(Object arg) {
if(chaged) {
for every observer on the list {
call update(this, arg)
}
changed = false;
}
}
notifyObservers() {
notifyObservers(null);
}
Observer Pattern 28
WeatherData
package javaobserver;
import java.util.Observable;
import java.util.Observer;
public class WeatherData extends Observable {
private int temperature;
public void measurementChanged() {
setChanged();
notifyObservers();
}
public void setMeasurements(int temperature) {
this.temperature = temperature;
measurementChanged();
}
public int getTemperature() {
return (int)(Math.random()*100);
}
}
Observer Pattern 29
TextDisplay (1)
public class TextDisplay extends JPanel
implements Observer, DisplayElement {
Observable observable;
private int temperature;
JLabel label;
public TextDisplay(Observable ob) {
label = new JLabel(" ");
add(label);
this.observable = ob;
observable.addObserver(this);
}
Observer Pattern 30
TextDisplay (2)
public void update(Observable o, Object arg) {
if (o instanceof WeatherData) {
WeatherData weatherData = (WeatherData)o;
this.temperature = weatherData.getTemperature();
display();
}
}
public void display() {
label.setText(""+temperature);
validate();
}
}
Observer Pattern 31