You are on page 1of 25

Observer Pattern

Part 2
Observer Pattern

• is useful when you want to keep your dependents in the know, when something they care about happens

• Observer Pattern is similar to the publisher + subscribers system

• in observer pattern

• publisher is the subject

• subscribers are the observers

• One-to-many relationship

• Subject & observer are loosely-coupled objects

• they interact, but know very little about each other

• Forth design principle: strive for loosely coupled design between objects that interact
Observer Pattern Definition

defines a one-to-many relationship between objects so


that when one object (subject) changes state all its
dependents (observers) get notified automatically
Weather application
example
• Consists of three main
components
Our focus is on
this part
• the weather station

• The hardware

• the WeatherData object


which tracks the weather WeatherData
coming from the weather object

station & updates the


display

• display device for presenting


the current weather to users
Recap: Analysis of the First
Try Design

• Area of change, can be encapsulated


• Programming to concrete implementation
which makes it difficult to modify; add/
remove new display requires modifying the
code
Design of the weather station using
observer pattern
Review Weather Station
Design/using Observer Pattern
• All observers implement one
common interface (Observer)

• Subject needs to know this


common interface to notify all
observers (displays)

• Concrete observers will have a


pointer to the Concrete
subject (WeatherData)

• to use it for example to add/


remove themselves
Weather App Design
Subject Implementation
public interface Subject {

• The registerObserver &


removeObserver both 

take observer object as public void registerObserver(Observer o);

an argument

public void removeObserver(Observer o);

• The notifyObservers () public void notifyObservers();

will be called when


there is a change to }

notify the observers


Weather App Design
Concrete Subject
Implementation public class WeatherData implements
Subject {

• The WeatherData private ArrayList observers;

implements the Subject private float temperature;



private float humidity;

interface
private float pressure;

public WeatherData() {

• Keep a list of all observers = new ArrayList();

observers
}

public void registerObserver(Observer o) {

• Three parameters;
observers.add(o);

temperature, humidity, public void removeObserver(Observer o) {

int i = observers.indexOf(o);


and pressure (state)


if (i >= 0) {

observers.remove(i); } }

public void notifyObservers() {



for (int i = 0; i < observers.size(); i++) {

Observer observer = (Observer)observers.get(i);

observer.update(temperature, humidity, pressure); } }

public void measurementsChanged() {

notifyObservers();

// other WeatherData methods here

}
Concrete Subject
Implementation public class WeatherData implements
Subject {

private ArrayList observers;

private float temperature;



private float humidity;

Implements the three private float pressure;

methods from the Subject public WeatherData() {

observers = new ArrayList();

interface
}

public void registerObserver(Observer o) {

• registerObserver() —> observers.add(o);

subscribe
}

public void removeObserver(Observer o) {

• removeObserver() —>
int i = observers.indexOf(o);

unsubscribe if (i >= 0) {

observers.remove(i);

public void notifyObservers() {



for (int i = 0; i < observers.size(); i++) {

Observer observer = (Observer)observers.get(i);

observer.update(temperature, humidity, pressure); } }

public void measurementsChanged() {

notifyObservers(); }

Concrete Subject
Implementation public class WeatherData implements
Subject {

• notifyObservers()

private ArrayList observers;

private float temperature;



private float humidity;

private float pressure;

• we know that all public WeatherData() {

observers implement
observers = new ArrayList();

the Observer interface, public void registerObserver(Observer o) {

so we notify them all in


observers.add(o); }

public void removeObserver(Observer o) {

the same way using the

int i = observers.indexOf(o);

if (i >= 0) {

update () method
observers.remove(i); } }

public void notifyObservers() {



• The measurementsChanged for (int i = 0; i < observers.size(); i++) {

() call the notifyObservers() Observer observer =


(Observer)observers.get(i);

observer.update(temperature, humidity,
pressure); } }

public void measurementsChanged() {

notifyObservers();

// other WeatherData methods here

Reading the Variables

• The WeatherData should read public void setMeasurements(

the values of the three


float temperature, float humidity, float pressure) {

variables; temperature,
humidity, and pressure
this.temperature = temperature;

this.humidity = humidity;

• To be able to test the code, this.pressure = pressure;

we define a set method, and


make this method call the measurementsChanged();

measurementChanged () }
Concrete Subject
public class WeatherData implements Subject {

1) Collection (ArrayList) to keep a list of all private ArrayList observers;


1
observers private float temperature;

private float humidity;

private float pressure;

public WeatherData() {
1
2) register/deregister an Observer from the observers = new ArrayList();}

Collection, doesn’t deal with concrete 2


observers public void registerObserver(Observer o) {

observers.add(o); }

public void removeObserver(Observer o) {


2
int i = observers.indexOf(o);

if (i >= 0) {

observers.remove(i); } }

3) When there is a change in the state of the 3


public void notifyObservers() {

variables, notify all observers for (int i = 0; i < observers.size(); i++) {

Observer observer = (Observer)observers.get(i);

observer.update(temperature, humidity, pressure); } }

public void measurementsChanged() {

3
notifyObservers(); }

// other WeatherData methods here

}
Weather App Design
Observer
public interface Observer {


public void update(float temp, float humidity, float pressure);

• A common interface that will be Variables that change state


implemented by all observers

• The update() method takes in the


three changing variables
Weather App Design
DisplayElement

public interface DisplayElement {

public void display();

• All observers (displays) need a display method so put in a superclass


Weather App Design
public class CurrentConditionsDisplay

implements Observer, DisplayElement {

private float temperature;


Concrete Observer private float humidity;


private Subject weatherData;

Implementation public CurrentConditionsDisplay(Subject weatherData)

• The concrete observer needs to this.weatherData = weatherData;


implement the Observer in order to
weatherData.registerObserver(this);

get change notification from the


Subject

• The constructor pass the


public void update(float temperature, float humidity,
WeatherData Subject as a
parameter
float pressure) {

• call the the registerObserver to this.temperature = temperature;



register itself with the Subject
this.humidity = humidity;


display();

• implement the update () method


from the Observer interface and call }

the display method which is


implemented from the public void display() {

DisplayInterface
System.out.println(“Current conditions: “ + temperature

+ “F degrees and “ + humidity + “% humidity”);

}
Concrete Observer
public class CurrentConditionsDisplay

implements Observer, DisplayElement {

private float temperature;



private float humidity;

Reference to the private Subject weatherData;

Subject object public CurrentConditionsDisplay(Subject weatherData) {

this.weatherData = weatherData;

weatherData.registerObserver(this);

Inherited from public void update(float temperature, float humidity, float pressure) {

the Observer this.temperature = temperature;



this.humidity = humidity;

display();

public void display() {



Inherited from
System.out.println(“Current conditions: “ + temperature

the
DisplayElement + “F degrees and “ + humidity + “% humidity”);

}}
Connect all components

public class WeatherStation {

public static void main(String[] args) {

WeatherData weatherData = new WeatherData(); 1

CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);

StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); 2

ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);

weatherData.setMeasurements(80, 65, 30.4f);

weatherData.setMeasurements(82, 70, 29.2f); 3

weatherData.setMeasurements(78, 90, 29.2f);

}}
How to communicate
changes
• push

• subjects sent details of changes to all observers

• pull

• subject only send a notify message that there is some


changes

• observer queries subject about the details


Summary
• Observer pattern can be applied when you want to keep your
dependent up-to-date with changes

• Observer pattern defines a one-to-many relationship between subject


& observers

• subject & observers are loosely coupled objects

• subject only knows that observers implement the observer


interface

• Two methods for communication between subject & observers

• push or pull

You might also like