Presentation is loading. Please wait.

Presentation is loading. Please wait.

The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.

Similar presentations


Presentation on theme: "The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1."— Presentation transcript:

1 The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1

2 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 ConsultingSlide 2

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

4 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 ConsultingSlide 4

5 Observer Pattern (continued) ©SoftMoore ConsultingSlide 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()

6 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. ©SoftMoore ConsultingSlide 6

7 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. ©SoftMoore ConsultingSlide 7

8 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 ConsultingSlide 8

9 Observer Pattern (continued) ©SoftMoore ConsultingSlide 9 : Observer: Subject: Observer update() Collaborations (continued) setState() notify() getState() update() getState()

10 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 ConsultingSlide 10

11 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 ConsultingSlide 11

12 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 ConsultingSlide 12

13 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 ConsultingSlide 13

14 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 ConsultingSlide 14

15 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 ConsultingSlide 15 The next few slides provide additional details on these examples of the Observer Pattern in Java.

16 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 ConsultingSlide 16

17 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. ©SoftMoore ConsultingSlide 17

18 ©SoftMoore ConsultingSlide 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.

19 ©SoftMoore ConsultingSlide 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).

20 ©SoftMoore ConsultingSlide 20 Illustration of Relationship Between Event Sources and Listeners Event Source Event Source Event Listener Event Listener Event Listener Event Source listens to all three sources listens to only one source has only one listener has two listeners has two listeners listens to only one source

21 ©SoftMoore ConsultingSlide 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

22 ©SoftMoore ConsultingSlide 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

23 ©SoftMoore ConsultingSlide 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); }

24 ©SoftMoore ConsultingSlide 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); }

25 ©SoftMoore ConsultingSlide 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) }

26 ©SoftMoore ConsultingSlide 26 Example: ButtonCounter (continued) button is an event source label is an event listener

27 addActionListener(label) ©SoftMoore ConsultingSlide 27 Sequence Diagram for the Example : JButtonlabel : CountingLabel doClick() actionPerformed(ev) : ButtonCounterFrame «create» ev : ActionEvent event sourceevent listenerevent object «create»

28 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. ©SoftMoore ConsultingSlide 28

29 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 ©SoftMoore ConsultingSlide 29


Download ppt "The Observer Pattern (Behavioral) ©SoftMoore ConsultingSlide 1."

Similar presentations


Ads by Google