CS#7250 (Design (Pa1erns (And (Refactoring (: Instructor: Awais Qasim
CS#7250 (Design (Pa1erns (And (Refactoring (: Instructor: Awais Qasim
Refactoring(
3
4
5
Weather'Monitoring'Applica7on'
The three players in the system are the
Humidity
Sensor
Pulls displays
Data
Temp Weather Weather Data Display
Sensor Station Object Device
Pressure
Sensor 6
7
8
Unpacking'the'WeatherData'class'
These three getter methods return the most recent weather
measurements for temperature, humidity and pressure respectively.
WeatherData
getTemperature()
getHumidity() /*(
getPressure() *(Call(this(method(
measurementsChanged()
*(whenever(measurements(are(
*(Updated(
*/(
Public(void(measurementsChanged(){(
( //(your(code(goes(here(
Update three }(
different displays
Problem'specica7on'
weatherData class has three
getter methods
measurementsChanged()
method called whenever there
is a change
Three display methods needs to
be supported: current
conditions, weather
statistics and simple
forecast
System should be expandable
First'cut'at'implementa7on'
registerObserver() Update()
removeObserver()
notifyObservers()
Observer'pa*ern''power'of'loose'coupling'
The only thing that the subject knows about an observer is
that it implements an interface
<<interface>>
rs
ob serve Observer <<interface>>
<<interface>>
Subject DisplayElement
update()
registerObserver() display()
removeObserver()
notifyObservers()
CurrentConditionsDisplay StatisticsDisplay
<<interface>>
rs
ob serve Observer <<interface>>
<<interface>>
Subject DisplayElement
update()
registerObserver() display()
removeObserver()
notifyObservers()
CurrentConditionsDisplay StatisticsDisplay
public(interface(Subject({(
( public(void(registerObserver(Observer(o);(
( public(void(removeObserver(Observer(o);(
( public(void(noMfyObservers();(
}(
public(interface(Observer({(
( public(void(update(oat(temp,(oat(humidity,(oat(pressure);(
}(
public(interface(DisplayElement({(
( public(void(display();(
}(
Implemen7ng'subject'interface'
public(class(WeatherData(implements(Subject({(
( private(ArrayList(observers;(
( private(oat(temperature;(
( private(oat(humidity;(
( private(oat(pressure;(
( (
( public(WeatherData()({(
( ( observers(=(new(ArrayList();(
( }(
( (
Register'and'unregister'
( public(void(registerObserver(Observer(o)({(
( ( observers.add(o);(
( }(
( (
( public(void(removeObserver(Observer(o)({(
( ( int(i(=(observers.indexOf(o);(
( ( if((i(>=(0)({(
( ( ( observers.remove(i);(
( ( }(
( }(
No7fy'methods'
public(void(noMfyObservers()({(
( ( for((int(i(=(0;(i(<(observers.size();(i++)({(
( (( Observer(observer(=((Observer)observers.get(i);(
( (( observer.update(temperature,(humidity,(pressure);(
( ( }(
}(
( (
( public(void(measurementsChanged()({(
( ( noMfyObservers();(
}(
public(void(setMeasurements(oat(temperature,(oat(humidity,(oat(pressure)({(
( this.temperature(=(temperature;(
( this.humidity(=(humidity;(
( this.pressure(=(pressure;(
( measurementsChanged();(
}(
Now,'lets'build'those'display'elements'
public class CurrentConditionsDisplay implements Observer, DisplayElement
{
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
public void display() {
System.out.println(Current conditions: + temperature
+ F degrees and + humidity + % humidity);
}
}
Why we store a reference to the
Subject? It doesnt look like we use
it again after the constructor?
Complete'Weather'Sta7on'
Output'
Observer(pa1ern(
More(analysis(
Push'or'pull'
The notification approach used so far pushes all the state to
all the observers
One can also just send a notification that some thing has
changed and let the observers pull the state information
<<interface>>
rs
ob serve Observer <<interface>>
Observable
DisplayElement
update()
addObserver()
deleteObserver() display()
notifyObservers()
setChanged()
CurrentConditionsDisplay StatisticsDisplay
update()
display()
How'Javas'builtOin'Observer'Pa*ern'works'
For an Object to become an observer.
Implement the Observer interface and call addObserver() on any
Observable object. Likewise, to remove yourself as an observer just call
deleteObserver().