Observer pattern

From Wikipedia, the free encyclopedia
  (Redirected from Observer design pattern)
Jump to: navigation, search

The observer 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, in "event driven" software. Most modern languages such as Java and C# have built in "event" constructs which implement the observer pattern components, for easy programming and short code.

The observer pattern is also a key part in the familiar model–view–controller (MVC) architectural pattern.[1] The observer pattern is implemented in numerous programming libraries and systems, including almost all GUI toolkits.

Strong vs. Weak reference[edit]

The observer pattern can cause memory leaks, known as the lapsed listener problem, because in basic implementation it requires both explicit registration and explicit deregistration, as in the dispose pattern, because the subject holds strong references to the observers, keeping them alive. This can be prevented by the subject holding weak references to the observers.

Coupling and typical pub-sub implementations[edit]

Typically, the observer pattern is implemented with the "subject" (which is being "observed") being part of the object who's state change is being observed, to be communicated to the observers upon occurrence. This type of implementation is considered "tightly coupled", forcing both the observers and the subject to be aware of each other and have access to their internal parts, creating possible issues of scalability, speed, message recovery and maintenance (also called event or notification loss), the lack of flexibility in conditional dispersion and possible hindrance to desired security measures. In some (non-polling) implementations of the publish-subscribe pattern (also called the pub-sub pattern), this is solved by creating a dedicated "message queue" server and at times an extra "message handler" object, as added stages between the observer and the observed object who's state is being checked, thus "decoupling" the software components. In these cases, the message queue server is accessed by the observers with the observer pattern, "subscribing to certain messages" knowing only about the expected message (or even that not), but knowing nothing about the message sender itself, and the sender may know nothing about the receivers. Other implementations of the publish-subscribe pattern, which achieve a similar effect of notification and communication to interested parties, do not use the observer pattern altogether.[2][3]

Still, in early implementations of multi-window operating systems like OS2 and Windows, the terms "publish-subscribe pattern" and "event driven software development" were used as a synonym for the observer pattern.[4]

The observer pattern, as described in the GOF book, is a very basic concept and does not deal with observance removal or with any conditional or complex logic handling to be done by the observed "subject" before or after notifying the observers. The pattern also does not deal with recording the "events", the asynchronous passing of the notifications or guaranteeing their being received. These concerns are typically dealt with in message queueing systems of which the observer pattern is only a small part.

Related patterns: Publish–subscribe pattern, mediator, singleton.

Structure[edit]

UML class diagram of Observer pattern

Example[edit]

Below is an example written in Java 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.

import java.util.Observable;
import java.util.Scanner;

class EventSource extends Observable implements Runnable {
    public void run() {
        while (true) {
            String response = new Scanner(System.in).next();
            setChanged();
            notifyObservers(response);
        }
    }
}
import java.util.Observable;
import java.util.Observer;

public class MyApp {
    public static void main(String[] args) {
        System.out.println("Enter Text: ");
        EventSource eventSource = new EventSource();

        eventSource.addObserver(new Observer() {
            public void update(Observable obj, Object arg) {
                System.out.println("Received response: " + arg);
            }
        });

        new Thread(eventSource).start();
    }
}
/*
interface Observer{
    public void update(Observable obj, Object arg);
}*/

A similar example in Python:

class Observable:
    def __init__(self):
        self.__observers = []
    
    def register_observer(self, observer):
        self.__observers.append(observer)
    
    def notify_observers(self, *args, **kwargs):
        for observer in self.__observers:
            observer.notify(self, *args, **kwargs)

class Observer:
    def __init__(self, observable):
        observable.register_observer(self)
    
    def notify(self, observable, *args, **kwargs):
        print('Got', args, kwargs, 'From', observable)


subject = Observable()
observer = Observer(subject)
subject.notify_observers('test')

See also[edit]

References[edit]

  1. ^ "Model-View-Controller". MSDN. Retrieved 2015-04-21. 
  2. ^ Comparison between different observer pattern implementations Moshe Bindler, 2015 (Github)
  3. ^ Differences between pub/sub and observer pattern The Observer Pattern by Adi Osmani (Safari books online)
  4. ^ The Windows Programming Experience Charles Petzold, Nov 10, 1992, PC Magazine (Google Books)

External links[edit]