Mastering the Observer Pattern: Real-World Examples and JavaScript Implementation
This article explains the Observer design pattern, its intent, real‑world analogies, advantages and drawbacks, and provides a complete JavaScript example with prototype‑based code to illustrate how publishers and subscribers interact in an event‑driven system.
Design patterns offer best practices for common programming problems, improving code readability, maintainability, reusability, development efficiency, and system flexibility. This article focuses on the Observer pattern.
The Observer pattern defines a one‑to‑many dependency between a subject (publisher) and its observers (subscribers). When the subject’s state changes, all registered observers are automatically notified.
Intent
The Observer pattern allows you to define a subscription mechanism so that multiple observers are notified when an object’s event occurs.
Problem
Consider two object types: Customer and Store. Customers check the store daily for a new product, but most visits are fruitless until the product arrives, or the store sends mass emails that may be considered spam.
This creates a dilemma: either customers waste time checking availability, or the store wastes resources notifying uninterested customers.
Solution
Objects with noteworthy state changes are called publishers . Objects that want to be informed are subscribers . The pattern suggests adding a subscription mechanism to the publisher, allowing objects to register or deregister for notifications.
The mechanism typically includes:
A list to store subscriber references.
Public methods to add or remove subscribers.
Publishers iterate over subscribers and invoke a notification method, keeping the publisher decoupled from concrete subscriber classes by using a common interface.
Real‑World Analogy
Magazine or newspaper subscriptions work similarly: the publisher maintains a subscriber list and sends new issues automatically, while subscribers can unsubscribe at any time.
JavaScript Example
// Observer interface
var Observer = function() {};
Observer.prototype.update = function(data) {};
// Concrete observers
var ConcreteObserver1 = function() {};
ConcreteObserver1.prototype = Object.create(Observer.prototype);
ConcreteObserver1.prototype.constructor = ConcreteObserver1;
ConcreteObserver1.prototype.update = function(data) {
console.log('ConcreteObserver1 received data: ' + data);
};
var ConcreteObserver2 = function() {};
ConcreteObserver2.prototype = Object.create(Observer.prototype);
ConcreteObserver2.prototype.constructor = ConcreteObserver2;
ConcreteObserver2.prototype.update = function(data) {
console.log('ConcreteObserver2 received data: ' + data);
};
// Subject (publisher)
var Subject = function() {
this.observers = [];
};
Subject.prototype.registerObserver = function(observer) {
this.observers.push(observer);
};
Subject.prototype.notifyObservers = function(data) {
for (var i = 0; i < this.observers.length; i++) {
this.observers[i].update(data);
}
};
// Concrete subject
var ConcreteSubject = function() {};
ConcreteSubject.prototype = Object.create(Subject.prototype);
ConcreteSubject.prototype.constructor = ConcreteSubject;
ConcreteSubject.prototype.setState = function(data) {
this.notifyObservers(data);
};The code defines an Observer interface with an update method, two concrete observers, a Subject that manages a list of observers, and a concrete subject that notifies observers when its state changes.
Beyond JavaScript, similar publish‑subscribe mechanisms exist in Redis, WebSockets, and other frameworks, enabling clients to subscribe to topics and receive automatic updates.
When to Use the Observer Pattern
When a change in one object must trigger changes in others.
When the set of dependent objects is unknown or changes dynamically.
In GUI components where actions (e.g., button clicks) need to notify listeners.
Implementation Steps
Identify core functionality that will act as the publisher.
Define a subscriber interface with at least an update method.
Create a publisher interface with methods to add/remove subscribers.
Implement storage for the subscriber list and the subscription methods.
Implement concrete publisher classes that call notifyObservers on important events.
Implement concrete subscriber classes that handle the notification data.
Instantiate subscribers and register them with the publisher.
Pros and Cons
Pros: reduces coupling, supports broadcast communication, adheres to the Open/Closed principle.
Cons: notifications can be time‑consuming, may introduce circular dependencies, and observers may lack context about why the subject changed.
In summary, the Observer pattern is ideal for any scenario requiring a one‑to‑many dependency, allowing automatic propagation of state changes from the subject to all observers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
