Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 31

Behavioral Patterns

Algorithms and the assignment of responsibilities among objects Describe not just patterns of objects or classes but also the patterns of communication between them Shift your focus away from flow of control to let you concentrate just on the way objects are interconnected Observer

Behavioral Patterns - Observer


Intent

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

Applicability

An abstraction has two aspects, one dependent on the other. When changing one object requires changing others, and you dont know how many objects need changed. When an object needs to notify others without knowledge about who they are.

Behavioral Patterns - Observer


An Example

Behavioral Patterns - Observer


Strucuture: Class Diagram

Subject *

<<interface>> Observer

attach( observer ) detach( observer ) notify()


for all o in observers o.update()

observers update()

ConcreteSubject subjectState getState()

observerState := subject.getState()

ConcreteObserver update()

subject

Behavioral Patterns - Observer


Participants

Subject

Knows its observers, but not their real identity. Provides an interface for attaching/detaching observers. Defines an updating interface for objects that should be identified of changes.

Observer

ConcreteSubject

Stores state of interest to ConcreteObserver objects. Sends update notice to observers upon state change.
Maintains reference to ConcreteSubject (sometimes). Maintains state that must be consistent with ConcreteSubject. Implements the Observer interface.

ConcreteObserver

Collaborations

ConcreteSubject notifies observers when changes occur. ConcreteObserver may query subject regarding state change.
5

Behavioral Patterns - Observer


Sequence Diagram
subject : ConcreteSubject attach( observer1 ) attach( observer2 ) observer1 : ConcreteObserver observer2 : ConcreteObserver

notify() update() getState() update() getState()

Behavioral Patterns - Observer


Consequences

Benefits

Abstract coupling between Subject and Observer


Can reuse subjects without reusing their observers and vice versa Observers can be added without modifying the subject All subject knows is its list of observers 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 broadcast communication: subject sends notification to all subscribed observers

Observers can be added/removed at any time

Liabilities

Possible cascading of notifications

Observers are not necessarily aware of each other and must be careful about triggering updates Simple update interface requires observers to deduce changed item
7

Behavioral Patterns - Observer


Implementation

How does the subject keep track of its observers?

Array, linked list

What if an observer wants to observe more than one subject?

Have the subject tell the observer who it is via the update interface The subject whenever its state changes The observers after they cause one or more state changes Some third party object(s)

Who triggers the update?


Make sure the subject updates its state before sending out notifications How much info about the change should the subject send to the observers?

Push Model - Lots Pull Model - Very Little


8

Behavioral Patterns - Observer


Implementation

Can the observers subscribe to specific events of interest?

If so, it's publish-subscribe

Can an observer also be a subject? What if an observer wants to be notified only after several subjects have changed state?

Use an intermediary object which acts as a mediator Subjects send notifications to the mediator object which performs any necessary processing before notifying the observers

Behavioral Patterns - Observer


MVC Example 1
This example shows the model and the view in the same class /** * Class CounterGui demonstrates having the model and view * in the same class. */ public class CounterGui extends Frame { // The counter. (The model!) private int counter = 0; // The view. private TextField tf = new TextField(10);

10

Behavioral Patterns - Observer


MVC Example 1
public CounterGui(String title) {

super(title); Panel tfPanel = new Panel(); tf.setText("0"); tfPanel.add(tf); add("North", tfPanel); Panel buttonPanel = new Panel(); Button incButton = new Button("Increment"); incButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { counter++; tf.setText(counter + ""); }
} ); buttonPanel.add(incButton);

11

Behavioral Patterns - Observer


MVC Example 1
Button decButton = new Button("Decrement"); decButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { counter--; tf.setText(counter + ""); } } );

buttonPanel.add(decButton); Button exitButton = new Button("Exit"); exitButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } } ); buttonPanel.add(exitButton); add("South", buttonPanel);

12

Behavioral Patterns - Observer


MVC Example 1
addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } ); } public static void main(String[] argv) { CounterGui cg = new CounterGui("CounterGui"); cg.setSize(300, 100); cg.setVisible(true); }

Where is the controller in this example? The controllers are the instances of the anonymous classes which handle the button presses.
13

Behavioral Patterns - Observer


MVC Example 2
This example shows the model and the view in separate classes First the view class: /** * Class CounterView demonstrates having the model and view * in the separate classes. This class is just the view. */ public class CounterView extends Frame { // The view. private TextField tf = new TextField(10); // A reference to our associated model. private Counter counter;

14

Behavioral Patterns - Observer


MVC Example 2
public CounterView(String title, Counter c) { super(title); counter = c; Panel tfPanel = new Panel(); tf.setText(counter.getCount()+ ""); tfPanel.add(tf); add("North", tfPanel); Panel buttonPanel = new Panel(); Button incButton = new Button("Increment"); incButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { counter.incCount(); tf.setText(counter.getCount() + ""); } } ); buttonPanel.add(incButton);
15

Behavioral Patterns - Observer


MVC Example 2
Button decButton = new Button("Decrement"); decButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { counter.decCount(); tf.setText(counter.getCount()+ ""); } } );

buttonPanel.add(decButton); Button exitButton = new Button("Exit"); exitButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } } ); buttonPanel.add(exitButton); add("South", buttonPanel);

16

Behavioral Patterns - Observer


MVC Example 2
addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } } );
public static void main(String[] argv) { Counter counter = new Counter(0); CounterView cv1 = new CounterView("CounterView1", counter); cv1.setSize(300, 100); cv1.setVisible(true); CounterView cv2 = new CounterView("CounterView2", counter); cv2.setSize(300, 100); cv2.setVisible(true); }

17

Behavioral Patterns - Observer


MVC Example 2
Next the model class:
/** * Class Counter implements a simple counter model. */ public class Counter { // The model. private int count;
public public public public } Counter(int count) { this.count = count; } int getCount() { return count; } void incCount() { count++; } void decCount() { count--; }

18

Behavioral Patterns - Observer


MVC Example 2 Note that we instantiated one model and two views in this example:

But we have a problem! When the model changes state, only one view updates! We need the Observer Pattern here!
19

Behavioral Patterns - Observer


MVC Example 3
This example shows the model and the view in separate classes with the model being observable. First the model class:
import java.util.Observable; /** * Class ObservableCounter implements a simple observable * counter model. */ public class ObservableCounter extends Observable { // The model. private int count; public ObservableCounter(int count) { this.count = count; }

20

Behavioral Patterns - Observer


MVC Example 3
public int getCount() { return count; } public void incCount() { count++; setChanged(); notifyObservers(); } public void decCount() { count--; setChanged(); notifyObservers(); }

21

Behavioral Patterns - Observer


MVC Example 3
Next the view class:
/** * Class ObservableCounterView demonstrates having the model * and view in the separate classes. This class is just the * view. */ public class ObservableCounterView extends Frame { // The view. private TextField tf = new TextField(10); // A reference to our associated model. private ObservableCounter counter;

22

Behavioral Patterns - Observer


MVC Example 3
public ObservableCounterView(String title, ObservableCounter c) { super(title); counter = c; // Add an anonymous observer to the ObservableCounter. counter.addObserver(new Observer() { public void update(Observable src, Object obj) { if (src == counter) { tf.setText(((ObservableCounter)src).getCount() + ""); } } } ); // Same GUI code as Example 2 not shown...

23

Behavioral Patterns - Observer


MVC Example 3
public static void main(String[] argv) { ObservableCounter counter = new ObservableCounter(0); ObservableCounterView cv1 = new ObservableCounterView("ObservableCounterView1", counter); cv1.setSize(300, 100); cv1.setVisible(true); ObservableCounterView cv2 = new ObservableCounterView("ObservableCounterView2", counter); cv2.setSize(300, 100); cv2.setVisible(true); }

24

Behavioral Patterns - Observer


MVC Example 3 Looking good now!

25

Appendix: More on the Observer Pattern


Decouples a subject and its observers Widely used in Smalltalk to separate application objects from interface objects Known in the Smalltalk world as Model-View-Controller (MVC) Rationale:
the interface is very likely to change while the underlying business objects remain stable

Defines a subject (the Observable) that is observed Allows multiple observers to monitor state changes in the subject without the subject having explicit knowledge about the existence of the observers
Observer Subject Observer Observer
26

More on the Observer Pattern The Model-View-Controller (MVC)


Developed at Xerox Parc to provide foundation classes for Smalltalk-80 The Model, View and Controller classes have more than a 10 year history Fundamental Principle

separate the underlying application MODEL (business objects) from the INTERFACE (presentation objects)

Rationale for MVC: Design for change and reuse


Business Objects (the Model in MVC) Expert Interface Novice Interface

MVC and Observer Pattern


In Smalltalk, objects may have dependents When an object announces I have changed, its dependents are notified It is the responsibility of the dependents to take action or ignore the notification
27

More on the Observer Pattern java.util.Observable


Observable/subject objects (the Model in Model-View) can announce that they have changed Methods:
void setChanged() void clearChanged() boolean hasChanged()

WHAT IF Observers query a Subject periodically?


query
Subject Observer

setChanged()

Harry

hasChanged() True/false
28

More on the Observer Pattern Implementing & Checking an Observable


Implementing an Observable
import java.util.*; import java.io.*; public class Harry extends Observable { private boolean maritalStatus = false; public Harry (boolean isMarried) { maritalStatus = isMarried; } public void updateMaritalStatus (boolean change) { maritalStatus = change; // set flag for anyone interested to check this.setChanged(); }

Checking an Observable
public static void main (String args [ ] ) { Harry harry = new Harry (false); harry.updateMaritalStatus (true); if (harry.hasChanged() ) System.out.println ("Time to call harry");

29

Appendix: More on the Observer Pattern Implementing the Observer Pattern


Step 1: Observers register with Observable
Harry

addObserver (this)

Observer1

addObserver (observer2)

Observer2

Step 2. Observable notifies Observers


notifyObservers(Object arg) update(Observable o, Object arg)

Harry

Observer1

Observable (Harry) may also send himself a notifyObservers() msg - no params


31

Appendix: More on the Observer Pattern java.util.Observable

The superclass of all observable objects to be used in the Model View design pattern

Methods are provided to:


void addObserver(anObserver) int countObservers() void deleteObserver (anObserver) void deleteObservers ()

Interface Defines the update() method that allows an object to observe subclasses of Observable Objects that implement the interface may be passed as parameters in:

addObserver(Observer o)
32

You might also like