| This article includes a list of references, related reading or external links, but its sources remain unclear because it lacks inline citations. Please improve this article by introducing more precise citations where appropriate. (July 2009) |
The observer pattern (a subset of the asynchronous publish/subscribe pattern) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems.
Contents |
Examples
| The Wikibook Computer Science/Design Patterns has a page on the topic of |
Below is an example that takes keyboard input and treats each input line as an event. The example is built upon the library classes java.util.Observer and java.util.Observable. When a string is supplied from System.in, the method notifyObservers is then called, in order to notify all observers of the event's occurrence, in the form of an invocation of their 'update' methods - in our example, ResponseHandler.update(...).
Java
The file MyApp.java contains a main() method that might be used in order to run the code.
/* File Name : EventSource.java */ package obs; import java.util.Observable; //Observable is here import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class EventSource extends Observable implements Runnable { public void run() { try { final InputStreamReader isr = new InputStreamReader( System.in ); final BufferedReader br = new BufferedReader( isr ); while( true ) { String response = br.readLine(); setChanged(); notifyObservers( response ); } } catch (IOException e) { e.printStackTrace(); } } }
/* File Name: ResponseHandler.java */ package obs; import java.util.Observable; import java.util.Observer; /* this is Event Handler */ public class ResponseHandler implements Observer { private String resp; public void update (Observable obj, Object arg) { if (arg instanceof String) { resp = (String) arg; System.out.println("\nReceived Response: "+ resp ); } } }
/* Filename : MyApp.java */ /* This is the main program */ package obs; public class MyApp { public static void main(String args[]) { System.out.println("Enter Text >"); // create an event source - reads from stdin final EventSource evSrc = new EventSource(); // create an observer final ResponseHandler respHandler = new ResponseHandler(); // subscribe the observer to the event source evSrc.addObserver( respHandler ); // starts the event thread Thread thread = new Thread(evSrc); thread.start(); } }
Here another example how to implement the observer pattern in java.
An observer interface which has an update method.
public interface IObserver { void update(String state); }
Two implementations of the Observer interface. Each implement the update method where they update their own state.
public class Observer1 implements IObserver { private String state; public String getState() { return state; } public void setState(String state) { this.state = state; } public void update(String state) { setState(state); System.out.println("Observer1 has received update signal with new state: " + getState()); } } public class Observer2 implements IObserver { private String state; public String getState() { return state; } public void setState(String state) { this.state = state; } public void update(String state) { setState(state); System.out.println("Observer2 has received update signal with new state: " + getState()); } }
This is the LogSubject which get observed by the Observers. It maintains a list of Observers. Everytime its state is changed, it runs the update method of all of the observers in its list changing their states as well.
public class LogSubject { private List<IObserver> observerList = new ArrayList<IObserver>(); private String state; public String getState() { return state; } public void attach(IObserver observer) { observerList.add(observer); } public void detach(IObserver observer) { observerList.remove(observer); } public void setState(String state) { this.state = state; stateChanged(); } private void stateChanged() { for (IObserver item: observerList) { item.update(getState()); } } }
And here the usage of the pattern above:
public class Client { public static void main(String[] args) { LogSubject subject = new LogSubject(); IObserver ob = new Observer(); IObserver ob1 = new Observer1(); IObserver ob2 = new Observer2(); subject.attach(ob); subject.attach(ob1); subject.attach(ob2); subject.setState("state1"); subject.setState("state2"); subject.detach(ob1); subject.setState("state3"); } }
Python
Here is a very basic implementation of the observer pattern in Python:
from collections import defaultdict class Observable (defaultdict): def __init__ (self): defaultdict.__init__(self, object) def emit (self, *args): '''Pass parameters to all observers and update states.''' for subscriber in self: response = subscriber(*args) self[subscriber] = response def subscribe (self, subscriber): '''Add a new subscriber to self.''' self[subscriber] def stat (self): '''Return a tuple containing the state of each observer.''' return tuple(self.values())
In the example above, a Python dictionary is overloaded to accept functions as keys whose return values are stored in corresponding slots in the dictionary. Below is a simple illustration. This class could easily be extended with an asynchronous notification method. Although this example stores functions as keys, it is conceivable that one could store user-defined class instances whose methods are accessed in a similar fashion.
myObservable = Observable () # subscribe some inlined functions. # myObservable[lambda x, y: x * y] would also work here. myObservable.subscribe(lambda x, y: x * y) myObservable.subscribe(lambda x, y: float(x) / y) myObservable.subscribe(lambda x, y: x + y) myObservable.subscribe(lambda x, y: x - y) # emit parameters to each observer myObservable.emit(6, 2) # get updated values myObservable.stat() # returns: (8, 3.0, 4, 12)
Implementations
The observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits.
Some of the most notable implementations of this pattern:
- The Java Swing library makes extensive use of the observer pattern for event management
- Boost.Signals, an extension of the C++ STL providing a signal/slot model
- The Qt C++ framework's signal/slot model
- libsigc++ - the C++ signalling template library.
- sigslot - C++ Signal/Slot Library
- XLObject - Template-based C++ signal/slot model patterned after Qt.
- Signals - A lightweight and non-intrusive C++ signal/slot model implementation.
- libevent - Multi-threaded Crossplatform Signal/Slot C++ Library
- GObject, in GLib - an implementation of objects and signals/callbacks in C. (This library has many bindings to other programming languages.)
- Exploring the Observer Design Pattern - the C# and Visual Basic .NET implementation, using delegates and the Event pattern
- Using the Observer Pattern, a discussion and implementation in REALbasic
- flash.events, a package in ActionScript 3.0 (following from the mx.events package in ActionScript 2.0).
- CSP - Observer Pattern using CSP-like Rendezvous (each actor is a process, communication is via rendezvous).
- YUI Event utility implements custom events through the observer pattern
- Py-notify, a Python implementation
- Event_Dispatcher, a PHP implementation
- Delphi Observer Pattern, a Delphi implementation
- .NET Remoting, Applying the Observer Pattern in .NET Remoting (using C#)
- PerfectJPattern Open Source Project, Provides a context-free and type-safe implementation of the Observer Pattern in Java.
- Cells, a dataflow extension to Common Lisp that uses meta-programming to hide some of the details of Observer pattern implementation.
- Publish/Subscribe with LabVIEW, Implementation example of Observer or Publish/Subscribe using G.
- SPL, the Standard PHP Library
- EventDispatcher singleton, a JavaScript core API based Signals and slots implementation - an observer concept different from Publish/subscribe - pretty lightweighted but still type-safety enforcing.
References
- http://www.research.ibm.com/designpatterns/example.htm
- http://msdn.microsoft.com/en-us/library/ms954621.aspx
- "Speaking on the Observer pattern" - JavaWorld
See also
- Design Patterns (book), the book which gave rise to the study of design patterns in computer science
- Design pattern (computer science), a standard solution to common problems in software design
- implicit invocation
- model-view-controller (MVC)
- client-server
External links
- Observer Pattern implementation in JDK 6
- A sample implementation in .NET
- Observer Pattern in Java
- Definition, C# example & UML diagram
- Jt J2EE Pattern Oriented Framework
|
|||||||||||
This entry is from Wikipedia, the leading user-contributed encyclopedia. It may not have been reviewed by professional editors (see full disclaimer)




