The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

29
The Observer Pattern (Behavioral) ©SoftMoore Consulting Slide 1

description

Motivation (continued) ©SoftMoore ConsultingSlide 3 Spreadsheet Data Table ViewBar GraphPie Chart request/modification change notification

Transcript of The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Page 1: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

The Observer Pattern(Behavioral)

©SoftMoore Consulting Slide 1

Page 2: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Motivation

• For many applications there is a need to maintain consistency between related objects without making classes tightly coupled.

• GUI toolkits need to separate the presentation aspects of the user interface from the underlying application data. (Recall the notions of models and views from the discussion of the MVC pattern.)

• For example, the data in a spreadsheet can be displayed in multiple ways, including– a table– a bar chart– a pie chart

©SoftMoore Consulting Slide 2

Page 3: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Motivation(continued)

©SoftMoore Consulting Slide 3

Spreadsheet Data

Table View Bar Graph Pie Chart

request/modification

change notification

Page 4: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern

• Intent: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

• Also Known As: Publish-Subscribe, Model-View• Applicability: Use the Observer pattern

– when a change to one object requires changing others, and you don’t know how many objects need to be changed.

– when an object should be able to notify other objects without making assumptions about who these objects are; i.e., you don’t want these objects tightly coupled.

– when an abstraction has two aspects, one dependent on the other. Encapsulating these aspects in separate objects lets you vary and reuse them independently.

©SoftMoore Consulting Slide 4

Page 5: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern(continued)

©SoftMoore Consulting Slide 5

Subject

attach(Observer)detach(Observer)notify()

ConcreteSubject

subjectState

getState()setState()

Observer

update()

ConcreteObserver

observerState

update()

for each o in observers o.update()

*observers

Structure

subject

observerState = subject.getState()

Page 6: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting

Observer Pattern(continued)

Participants• Subject

– knows its observers. Any number of Observer objects may observe a subject.

– provides an interface for attaching and detaching Observer objects.

• Observer– defines an updating interface for objects that should be notified

of changes in a subject.

• ConcreteSubject– stores state of interest to ConcreteObserver objects.– sends a notification to its observers when its state changes.

Slide 6

Page 7: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting

Observer Pattern(continued)

Participants (continued)

• ConcreteObserver– maintains a reference to a ConcreteSubject object.– stores state that should stay consistent with the subject’s state.– implements the Observer updating interface to keep its state

consistent with the subject’s state.

Slide 7

Page 8: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern(continued)

Collaborations• ConcreteSubject notifies its observers whenever a

change occurs that could make its observers’ state inconsistent with its own.

• After being informed of a change in the concrete subject, a ConcreteObserver object may query the subject for information. ConcreteObserver uses this information to reconcile its state with that of the subject.

©SoftMoore Consulting Slide 8

Page 9: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern(continued)

©SoftMoore Consulting Slide 9

: Observer: Subject : Observer

update()

Collaborations (continued)

setState()

notify()

getState()

update()

getState()

Page 10: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern(continued)

Consequences• Minimal coupling between the Subject and the Observer

– Subjects can be reused without reusing their observers, and vice versa.

– Observers can be added without modifying the subject.– A subject knows only that it has a list of observers.– A subject does not need to know the concrete class of an

observer, just that each observer implements the update interface.

– Subject and observer can belong to different abstraction layers.

• Support for event broadcasting– Subject sends notification to all subscribed observers.– Observers can be added/removed at any time.

©SoftMoore Consulting Slide 10

Page 11: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern(continued)

Consequences (continued)

• Possible cascading of notifications– Observers are not necessarily aware of each other and must be

careful about triggering updates.– Simple update interface provides no details on what changed in

the subject. Observers are required to deduce changes to the subject.

©SoftMoore Consulting Slide 11

Page 12: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern(continued)

Implementation• Mapping subjects to their observers.

– simplest way is for subject to maintain a list of explicit references to its observers (storage overhead).

– can use a hash table to maintain subject-to-observer mapping.

• Observing more than one subject.– must modify the update interface to let the observer know the

identity of the subject that sent the update notification; e.g.,notify(this);

• Who triggers the update?– require subject’s state-setting methods to call notify().– make clients responsible for calling notify() after a change.

©SoftMoore Consulting Slide 12

Page 13: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern(continued)

Implementation (continued)

• How to handle dangling references to deleted subjects.• Making sure Subject state is self consistent before

notification.– can be avoided by sending notifications from Template Methods

in the abstract Subject class.

• Avoiding observer-specific update protocols.– push model: subject sends observers detailed information

about the change, whether they want it or not.– pull model: subject sends nothing but the notification that it

changed, and observers must query the subject to determine what changed and whether or not they need to handle it.

©SoftMoore Consulting Slide 13

Page 14: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern(continued)

Implementation (continued)• Specifying modifications of interest explicitly.

– can improve efficiency by extending a subject’s interface to allow observers to register for specific events of interest

– subjects have aspects, and observers can register interest in some aspects but not others.

• Encapsulating complex update semantics; e.g., by using a ChangeManager object with these responsibilities:– maps subjects to observers– defines update strategy– updates all dependent observers at the request of a subject.

©SoftMoore Consulting Slide 14

Page 15: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Observer Pattern in Java

• Package java.util provides– an interface Observer that observers can implement when they

need to be identified of a change.– a class named Observable that subjects can extend that

manages the list of observers.

• Java Message Service (JMS) supports a publish/subscribe model for messaging that is based on the observer pattern.

• Since version 1.1, the Java event model is based on the observer pattern.

©SoftMoore Consulting Slide 15

The next few slides provide additional details onthese examples of the Observer Pattern in Java.

Page 16: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

From Package java.util

public interface Observer { public void update(Observable o, Object arg); }

public class Observable { public synchronized void addObserver(Observer o); public synchronized void deleteObserver(Observer o); public void notifyObservers(); public void notifyObservers(Object arg); ... }

©SoftMoore Consulting Slide 16

Page 17: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting

JMS

• The Java Message Service (JMS) is a messaging API that allows application components to create, send, receive, and read messages. It enables distributed communication that is loosely coupled, reliable, and asynchronous.

• The JMS API supports two models for messaging:– point-to-point– publish/subscribe

• The publish/subscribe model is essentially an implementation of the observer pattern.

Slide 17

Page 18: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 18

Event Sources, Listeners, and Objects

• Events are transmitted from event sources (e.g., buttons or scrollbars) to event listeners.

• An event source is an object that knows when/how the event occurs. Event sources report on events.

• An event listener is an object that needs to be notified when a certain event occurs in order to perform some action in response to the event. Any object can be designed to be an event listener.

• Information about the event is encapsulated in an event object. The class of an event object must ultimately inherit from java.util.EventObject.

Page 19: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 19

Summary of Event Handling in Java

• An event source must be able to register listener objects and send them event objects.

• A listener object implements a special listener interface.• When an event occurs, the source notifies all registered

listeners by calling the appropriate method of the listener interface.

• When a listener is notified that an event has occurred, it is up to the listener to determine the appropriate course of action (including ignoring the event).

Page 20: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 20

Illustration of Relationship BetweenEvent Sources and Listeners

EventSource

EventSource

EventListener

EventListener

EventListener

EventSource

listens toall threesources

listens toonly onesource

has onlyone listener

has twolisteners

has twolisteners

listens toonly onesource

Page 21: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 21

Handling Button Events

• When a button is pushed, it generates an object of class ActionEvent

• A button is an event source for an ActionEvent, so it allows objects to register as listeners for such events; it provides method addActionListener(ActionListener l)

java.util.EventObject

java.awt.AWTEvent

java.awt.ActionEvent

Page 22: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 22

Handling Button Events(continued)

• If another object wants to be notified when a button is pushed, the object will need to– implement the ActionListener interface

public interface ActionListener extends EventListener { /** * Invoked when an action occurs. */ public void actionPerformed(ActionEvent e); }

– register with the button by calling its addActionListener() method

Page 23: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 23

Example: ButtonCounter

package com.softmoore.swing;

import java.awt.*;import java.awt.event.*;import javax.swing.*;

public class ButtonCounter { public static void main(String[] args) { ButtonCounterFrame frame = new ButtonCounterFrame(); frame.setVisible(true); } }

Page 24: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 24

Example: ButtonCounter(continued)

class ClickCountingLabel extends JLabel implements ActionListener { private static final String LABEL_TEXT_PREFIX = "Number of button clicks = ";

private int numClicks = 0;

public ClickCountingLabel() { super(); setText(LABEL_TEXT_PREFIX + numClicks); }

public void actionPerformed(ActionEvent event) { ++numClicks; setText(LABEL_TEXT_PREFIX + numClicks); } }

Page 25: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 25

Example: ButtonCounter(continued)

class ButtonCounterFrame extends JFrame { public ButtonCounterFrame() { // ... set up the frame and center it on the screen // ... create panels for the button and label ClickCountingLabel label = new ClickCountingLabel(); labelPanel.add(label);

JButton button = new JButton("Click Me!"); button.addActionListener(label); buttonPanel.add(button);

add(buttonPanel, BorderLayout.NORTH); add(labelPanel, BorderLayout.CENTER);

// ... add panels to frame (to its content pane) } }

Page 26: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting Slide 26

Example: ButtonCounter(continued)

button is an event sourcelabel is an event listener

Page 27: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

addActionListener(label)

©SoftMoore Consulting Slide 27

Sequence Diagram for the Example

: JButton label : CountingLabel

doClick()

actionPerformed(ev)

: ButtonCounterFrame

«create»

ev : ActionEvent

event source event listener event object

«create»

«create»

Page 28: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting

Related Patterns

• If a ChangeManager is used, it acts as a Mediator between subjects and observers.

• A ChangeManager would often be implemented as a Singleton.

Slide 28

Page 29: The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

©SoftMoore Consulting

References

• Observer pattern (Wikipedia)http://en.wikipedia.org/wiki/Observer_pattern

• Observer Pattern (Object-Oriented Design)http://www.oodesign.com/observer-pattern.html

• Exploring the Observer Design Pattern(Purdy and Richter)http://msdn.microsoft.com/en-us/library/ee817669.aspx

Slide 29