The Observer Pattern SE2811 Dr Mark L Hornick
The Observer Pattern SE-2811 Dr. Mark L. Hornick 1
Observer Pattern Context A system contains objects exhibiting: l l l One-to-many dependency between objects One object changes state All dependents are notified and updated automatically
What are we trying to achieve with the Observer Pattern ? l Separation of software subsystems l l Loosely-coupled classes l l Separation between GUI & Domain objects Because tightly-coupled classes reduce reusability & understanding A generic/elegant way for the classes to communicate
Key components in the Observer Pattern l Subject l l Subject has dependent observers. Observer(s) l When the state of the subject changes, each dependent observer is notified.
Generic Subject class Subject. Class implements Subject { public Subject. Class(); public void attach(Observer obs); public void detach(Observer obs); public void notify. Observers(); private Collection<Observer> observers; } Note: Some texts define a notify() instead of notify. Observers() method. However, Java’s Object class already has a notify() method, which we don’t want to override.
Generic Observer class Observer. Class implements Observer { public Observer. Class(); public void update(? ? ? ); } What is the appropriate argument for the update() method?
Basic class relationships Subject ---------------attach(): void detach(): void notify. Observers(): void Observer -observers --------update(? ? ? ): void 1. . * Observer. Class 1 Subject. Class Observer. Class 2 7
Collaborations between objects in the Observer pattern s: Subject. Class o 1: Observer. Class 1 o 2: Observer. Class 2 attach() notify. Observers() update(? ? ? ) get. Context. Specific. Info() 8
Weather Program example class Weather. Data implements Subject { //private data attributes List<Observer> observers; . . . public Weather. Data(){…} public void get. Temp() {…} public int get. Wind. Speed() {…} public void attach(Observer obs) {…} public void detach(Observer obs) {…} public void notify. Observers() {…}. . . }
Example (contd. ) public void acquire. Data. From. Sensors() { // acquire updated weather data …… notify. Observers(); // notify observers }
Example (contd. ) class main. Display extends Observer { public main. Display (Weather. Data wd){. . . } public void update(? ? ? ) {. . . } public void update. Display. UI() {. . . } }
Example (contd. ) public main. Display(Weather. Data wd) { Subject wd. Subject = wd; wd. Subject. attach(this); } // What do we pass to update()? public void update(? ? ? ) { // How do we get data from the Subject? update. Display. UI(? ? ? ); // main. Display class method }
Implementation Questions l l l What should be the arguments of the update method? Should we send the Subject as the argument? Should each instance of the Observer store the “concrete subject” as a data attribute, or just an Interface reference? Can Subject be an abstract class instead of an Interface?
Consequences (positive) Coupling between Subject and Observers: l l l Subject knows it has a list of Observers, but not specific classes Each Observer conforms to the simple interface of the abstract Observer Interface. Hence, coupling is l l Abstract Minimal
Consequences (negative) l Broadcast communication l l Notification is broadcast to all interested objects. Observers can be added/removed at any time. Observer decides when it needs to be notified. Unexpected updates l Observers have no knowledge l l l Of each other’s presence. About the cost of “state change of subject” Cascade of updates.
- Slides: 15