In software design and software engineering, the observer pattern is a software design pattern in which an object, called the subject (also known as event source or event stream), maintains a list of its dependents, called observers (also known as event sinks), and automatically notifies them of any state changes, typically by calling one of their methods. The subject knows its observers through a standardized interface and manages the subscription list directly.
This pattern creates a one-to-many dependency where multiple observers can listen to a single subject, but the coupling is typically synchronous and direct—the subject calls observer methods when changes occur, though asynchronous implementations using event queues are possible. Unlike the publish-subscribe pattern, there is no intermediary broker; the subject and observers have direct references to each other.
It is commonly used to implement event handling systems in event-driven programming, particularly in-process systems like GUI toolkits or MVC frameworks. This makes the pattern well-suited to processing data that arrives unpredictably—such as user input, HTTP requests, GPIO signals, updates from distributed databases, or changes in a GUI model.
Overview
The observer design pattern is a behavioural pattern listed among the 23 well-known "Gang of Four" design patterns that address recurring design challenges in order to design flexible and reusable object-oriented software, yielding objects that are easier to implement, change, test, and reuse.
The observer pattern addresses the following requirements:
- A one-to-many dependency between objects should be defined without making the objects tightly coupled.
- When one object changes state, an open-ended number of dependent objects should be updated automatically.
- An object can notify multiple other objects.
The naive approach would be for one object (subject) to directly call specific methods on each dependent object. This creates tight coupling because the subject must know the concrete types and specific interfaces of all dependent objects, making the code inflexible and hard to extend. However, this direct approach may be preferable in performance-critical scenarios (such as low-level kernel structures or real-time systems) where the overhead of abstraction is unacceptable and compile-time optimization is crucial.
The observer pattern provides a more flexible alternative by establishing a standard notification protocol:
- Define <code>Subject</code> and <code>Observer</code> objects with standardized interfaces.
- When a subject changes state, all registered observers are notified and updated automatically.
- The subject manages its own state while also maintaining a list of observers and notifying them of state changes by calling their <code>update()</code> operation.
- The responsibility of observers is to register and unregister themselves with a subject (in order to be notified of state changes) and to update their state (to synchronize it with the subject's state) when they are notified.
This approach makes subject and observers loosely coupled through interface standardization. The subject only needs to know that observers implement the <code>update()</code> method—it has no knowledge of observers' concrete types or internal implementation details. Observers can be added and removed independently at run time.
Relationship to publish–subscribe
The observer pattern and the publish–subscribe pattern are closely related and often confused, as both support one-to-many communication between components. However, they differ significantly in architecture, degree of coupling, and common use cases.
The table below summarizes the key differences:
{| class="wikitable"
!Feature
!Observer Pattern
!Publish–Subscribe Pattern
|-
|Coupling
|Tightly coupled — the subject holds direct references to its observers via a standardized interface.
|Loosely coupled — publishers and subscribers are unaware of each other.
|-
|Communication
|Direct — the subject calls observer methods, typically synchronously.
|Indirect — a broker (message bus or event manager) dispatches messages to subscribers.
|-
|Knowledge of Participants
|The subject knows its observers.
|Publisher and subscriber are decoupled; neither knows about the other.
|-
|Scalability
|Suitable for in-process systems like GUI toolkits.
|More scalable; supports distributed systems and asynchronous messaging.
|-
|Synchronous or Asynchronous
|Typically synchronous but can be asynchronous with event queues.
|Typically asynchronous but can be synchronous.
|-
|Filtering
|Limited — observers receive all events and filter internally.
|Rich filtering — brokers may filter by topic, content, or rules.
|-
|Fault Tolerance
|Observer failures can affect the subject.
|Failures are isolated; the broker decouples participants.
|-
|Typical Usage
|GUI frameworks, MVC architecture, local object notifications.
|Microservices, distributed systems, messaging middleware.
|}
In practice, publish–subscribe systems evolved to address several limitations of the observer pattern. A typical observer implementation creates a tight coupling between the subject and its observers. This may limit scalability, flexibility, and maintainability, especially in distributed environments. Subjects and observers must conform to a shared interface, and both parties are aware of each other’s presence.
To reduce this coupling, publish–subscribe systems introduce a message broker or event bus that intermediates between publishers and subscribers. This additional layer removes the need for direct references, allowing systems to evolve independently. Brokers may also support features like message persistence, delivery guarantees, topic-based filtering, and asynchronous communication.
In some systems, the observer pattern is used internally to implement subscription mechanisms behind a publish–subscribe interface. In other cases, the patterns are applied independently. For example, JavaScript libraries and frameworks often offer both observer-like subscriptions (e.g., via callback registration) and decoupled pub-sub mechanisms (e.g., via event emitters or signals).
Historically, in early graphical operating systems like OS/2 and Microsoft Windows, the terms "publish–subscribe" and "event-driven programming" were often used as synonyms for the observer pattern.
The observer pattern, as formalized in Design Patterns,]]
In this UML class diagram, the <code>Subject</code> class does not update the state of dependent objects directly. Instead, <code>Subject</code> refers to the <code>Observer</code> interface (<code>update()</code>) for updating state, which makes the <code>Subject</code> independent of how the state of dependent objects is updated. The <code>Observer1</code> and <code>Observer2</code> classes implement the <code>Observer</code> interface by synchronizing their state with subject's state.
The UML sequence diagram shows the runtime interactions: The <code>Observer1</code> and <code>Observer2</code> objects call <code>attach(this)</code> on <code>Subject1</code> to register themselves. Assuming that the state of <code>Subject1</code> changes, <code>Subject1</code> calls <code>notify()</code> on itself. <code>notify()</code> calls <code>update()</code> on the registered <code>Observer1</code> and <code>Observer2</code>objects, which request the changed data (<code>getState()</code>) from <code>Subject1</code> to update (synchronize) their state.
UML class diagram
none|thumb|500x500px|[[Unified Modeling Language|UML class diagram of Observer pattern]]
Example
<!-- Wikipedia is not a list of examples. Do not add examples from your favorite programming language here; this page exists to explain the design pattern, not to show how it interacts with subtleties of every language under the sun. Feel free to add examples here: http://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Observer -->
While the library classes <code>java.util.Observer</code> and <code>java.util.Observable</code> exist, they have been deprecated in Java 9 because the model implemented was quite limited.
Below is an example written in Java that takes keyboard input and handles each input line as an event. When a string is supplied from <code>System.in</code>, the method <code>notifyObservers()</code> is then called in order to notify all observers of the event's occurrence, in the form of an invocation of their update methods.
Java
<syntaxhighlight lang="java">
package org.wikipedia.examples;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
interface Observer {
void update(String event);
}
class EventSource {
List<Observer> observers = new ArrayList<>();
public void notifyObservers(String event) {
observers.forEach(observer -> observer.update(event));
}
public void addObserver(Observer observer) {
observers.add(observer);
}
public void scanSystemIn() {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
notifyObservers(line);
}
}
}
public class ObserverDemo {
public static void main(String[] args) {
System.out.println("Enter Text: ");
EventSource eventSource = new EventSource();
eventSource.addObserver(event -> System.out.printf("Received response: %s%n", event));
eventSource.scanSystemIn();
}
}
</syntaxhighlight>
C#
C# provides the . and interfaces as well as documentation on how to implement the design pattern.
<syntaxhighlight lang="csharp">
namespace Wikipedia.Examples;
using System;
using System.Collections.Generic;
class Payload
{
internal string Message { get; init; }
}
class Subject : IObservable<Payload>
{
private readonly List<IObserver<Payload>> _observers = new();
IDisposable IObservable<Payload>.Subscribe(IObserver<Payload> observer)
{
if (!_observers.Contains(observer))
{
_observers.Add(observer);
}
return new Unsubscriber(observer, _observers);
}
internal void SendMessage(string message)
{
foreach (IObserver<Payload> observer in _observers)
{
observer.OnNext(new Payload { Message = message });
}
}
}
internal class Unsubscriber : IDisposable
{
private readonly IObserver<Payload> _observer;
private readonly ICollection<IObserver<Payload>> _observers;
internal Unsubscriber(
IObserver<Payload> observer,
ICollection<IObserver<Payload>> observers)
{
_observer = observer;
_observers = observers;
}
void IDisposable.Dispose()
{
if (_observer != null && _observers.Contains(_observer))
{
_observers.Remove(_observer);
}
}
}
internal class Observer : IObserver<Payload>
{
private string _message;
public void OnCompleted()
{
}
public void OnError(Exception error)
{
}
public void OnNext(Payload value)
{
_message = value.Message;
}
internal IDisposable Register(IObservable<Payload> subject)
{
return subject.Subscribe(this);
}
}
</syntaxhighlight>
C++
This is a C++23 implementation.
<syntaxhighlight lang="c++">
import std;
using std::reference_wrapper;
using std::vector;
class Subject; // Forward declaration for usage in Observer
class Observer {
private:
// Reference to a Subject object to detach in the destructor
Subject& subject;
public:
explicit Observer(Subject& subj):
subject{subj} {
subject.attach(*this);
}
virtual ~Observer() {
subject.detach(*this);
}
Observer(const Observer&) = delete;
Observer& operator=(const Observer&) = delete;
virtual void update(Subject& s) const = 0;
};
// Subject is the base class for event generation
class Subject {
private:
vector This would fire events upon change to the observed object. Without the deprecated function, the pattern may be implemented with more explicit code:
<syntaxhighlight lang="javascript">
let Subject = {
_state: 0,
_observers: [],
add: function(observer) {
this._observers.push(observer);
},
getState: function() {
return this._state;
},
setState: function(value) {
this._state = value;
for (let i = 0; i < this._observers.length; i++)
{
this._observers[i].signal(this);
}
}
};
let Observer = {
signal: function(subject) {
let currentValue = subject.getState();
console.log(currentValue);
}
}
Subject.add(Observer);
Subject.setState(10);
// Output in console.log - 10
</syntaxhighlight>
See also
- Implicit invocation
- Client–server model
- The observer pattern is often used in the entity–component–system pattern
