the observer pattern · the observer pattern † intent: define a one-to-many dependency between...

Post on 15-Jul-2020

12 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Supplement toThe Design and Implementation of Multimedia Software

The Observer Pattern

Prof. David Bernstein

James Madison University

users.cs.jmu.edu/bernstdh

D. Bernstein (JMU) Observer www.cs.jmu.edu 1 / 21

Motivation

• Objects often need to communicate with each other

• Traditional message passing techniques tend to couple objects tootightly

D. Bernstein (JMU) Observer www.cs.jmu.edu 2 / 21

An Example

A security (e.g., stocks, futures, options) trading application in whichthere is a TickReader that reads “tick by tick” pricing information(e.g., from the Internet) and sends each Tick to a TickWriter thatsaves the information in a file and to a TickerTape that displays theinformation on a screen.

D. Bernstein (JMU) Observer www.cs.jmu.edu 3 / 21

An Example - A Bad Design

Think of the TickReader as actively adding ticks to the TickWriterand TickerTape.

D. Bernstein (JMU) Observer www.cs.jmu.edu 4 / 21

Problems with this Design

• Because TickReader calls the TickWriter and TickerTape it isnot very re-usable

• Every TickReader must have an associated TickWriter andTickerTape

D. Bernstein (JMU) Observer www.cs.jmu.edu 5 / 21

An Example - A Better Design

Think of the TickWriter and TickerTape as passively listening for“ticks”. Then, a TickReader need only have a list of (zero or more)TickListener objects that it will inform.

D. Bernstein (JMU) Observer www.cs.jmu.edu 6 / 21

The Observer Pattern

• Intent:Define a one-to-many dependency between objects so that when oneobject changes state, all of its dependents are notified

• Participants:A subject

Some observers

D. Bernstein (JMU) Observer www.cs.jmu.edu 7 / 21

One Implementation

D. Bernstein (JMU) Observer www.cs.jmu.edu 8 / 21

Another Implementation

D. Bernstein (JMU) Observer www.cs.jmu.edu 9 / 21

Issues Related to the Choice of Collection

• Frequency of notifications vs. modifications (compare Hashtableor HashMap with Vector or ArrayList)

• Need for concurrent notifications and modifications (think aboutCopyOnWriteArrayList)

D. Bernstein (JMU) Observer www.cs.jmu.edu 10 / 21

Other Terminology

• Listener

• Publish-Subscribe

D. Bernstein (JMU) Observer www.cs.jmu.edu 11 / 21

A Complete Example

• A Silly Text Processor:Counts the number of words that start with an uppercase letter

Save the lines to a file

Shows the progress (e.g., then number of lines processed)

• Some Observations:This is not going to make us any money

We can use it to explore different designs

D. Bernstein (JMU) Observer www.cs.jmu.edu 12 / 21

A Design that is Not Cohesive

D. Bernstein (JMU) Observer www.cs.jmu.edu 13 / 21

A Design that is Tightly Coupled

D. Bernstein (JMU) Observer www.cs.jmu.edu 14 / 21

A Good Design

D. Bernstein (JMU) Observer www.cs.jmu.edu 15 / 21

The LineObserver Interface

public interface LineObserver

{

public void handleLine(LineSubject source);

}

D. Bernstein (JMU) Observer www.cs.jmu.edu 16 / 21

The LineSubject Interface

public interface LineSubject

{

public void addObserver(LineObserver observer);

public String getLine();

public void notifyObservers();

public void removeObserver(LineObserver observer);

}

D. Bernstein (JMU) Observer www.cs.jmu.edu 17 / 21

The LineReader

import java.io.*;

import java.util.*;

public class LineReader implements LineSubject

{

private BufferedReader in;

private List<LineObserver> observers;

private int maxLines;

private String line;

public LineReader(InputStream is, int maxLines) throws IOException

{

this.maxLines = maxLines;

in = new BufferedReader(new InputStreamReader(is));

observers = new LinkedList<LineObserver>();

}

public void addObserver(LineObserver observer)

{

observers.add(observer);

}

D. Bernstein (JMU) Observer www.cs.jmu.edu 18 / 21

The LineReader (cont.)

public String getLine()

{

return line;

}

public void notifyObservers()

{

Iterator<LineObserver> i;

LineObserver observer;

i = observers.iterator();

while (i.hasNext())

{

observer = i.next();

observer.handleLine(this);

}

}

public void removeObserver(LineObserver observer)

{

observers.remove(observer);

}

D. Bernstein (JMU) Observer www.cs.jmu.edu 19 / 21

The LineReader (cont.)

public void start() throws IOException

{

// Read from the console and alert listeners

while ((line = in.readLine()) != null)

{

notifyObservers();

}

}

}

D. Bernstein (JMU) Observer www.cs.jmu.edu 20 / 21

The SillyTextProcessor

// Initialization

reader = new LineReader(System.in, maxLines);

bar = new ProgressWindow(maxLines);

archiver = new LineArchiver();

counter = new UCWordCounter();

reader.addObserver(bar);

reader.addObserver(archiver);

reader.addObserver(counter);

// Prompt the user

System.out.println("Enter " +maxLines +

" lines of text (^Z to end):\n");

reader.start();

D. Bernstein (JMU) Observer www.cs.jmu.edu 21 / 21

top related