ProgramGuru

Observer Pattern

Observer: start from the problem

See the responsibilities

SubjectOwns subscription registration
NotificationAnnounces a local change
ObserversReceive callbacks
UnsubscribeEnds a callback’s lifetime
Subject: Owns subscription registration → Notification: Announces a local change → Observers: Receive callbacks → Unsubscribe: Ends a callback’s lifetime

A local order model has a dashboard and an audit view interested in changes. Calling each view directly from every update couples the model to the current subscriber list.

This is a behavioral pattern lesson. Follow the responsibilities, inspect the small JavaScript example and compare the design choices. The example is local teaching code; its boundary is explained before you apply the idea to a real service.

What you’ll learn

  • Explain the problem Observer addresses and the roles involved.
  • Follow the example and distinguish this pattern from nearby alternatives.
  • Choose when the benefit justifies the extra responsibilities and testing.

How the responsibilities work

Observer lets subscribers register for notifications from a subject. The subject announces a change through a common callback contract. Subscribers can be added or removed without the subject naming every concrete view.

Our in-process subject uses a Set of callbacks and returns an unsubscribe function. Delivery is synchronous in this example. It does not persist an event or retry a callback after a process crash.

Follow a small example

Read the JavaScript from top to bottom and compare the expected output. The values are chosen to make this pattern’s responsibility visible. This example runs in one local execution context; it does not create remote services, durable storage or production access controls.

JavaScript · local teaching example

const listeners = new Set();
function subscribe(listener) {
  listeners.add(listener);
  return () => listeners.delete(listener);
}
function announce(value) { for (const listener of listeners) listener(value); }
const stop = subscribe(value => console.log('View: ' + value));
announce('order ready');
stop();
announce('order shipped');

Expected output

View: order ready

Choose a design and inspect the consequence

Compare the design choices

A view is removed from the screen.
Subscribers are in separate services.

Compare the visible consequences. With JavaScript enabled, choose an option in each scenario to assemble your decision record.

This is an exploratory design exercise. It does not run infrastructure, measure capacity or replace the lesson’s quiz.

Use the consequences to explain your decision, including the simpler alternative.

Apply the pattern to two situations. Select one option in each situation to build a decision record. Every option and its consequence stays visible, and you can change your choices.

When it helps—and what it costs

Use it for local event relationships where registration and callback lifetimes are clear. Define whether notifications describe the state after a successful change.

Forgotten subscriptions can retain objects. Callback errors, ordering and reentrant updates need policies. In this minimal loop, one throwing callback can prevent later callbacks running; production code must decide how such failures are isolated and observed.

Distinguish the neighbouring patterns

Publisher/Subscriber through a broker can decouple processes and add delivery contracts. Observer often describes a local subject/subscriber relationship; neither name alone guarantees durable delivery.

Follow broker-mediated subscriptions, coordinating interactions, the meaning and commit point of events to compare the specific responsibility before combining patterns.

Check your pattern reasoning

Why is there no second printed notification?
Choose one answer. You can try again.

Answer and explanation

The observer unsubscribed before the next announcement.

Registration has an explicit lifetime.

Check your pattern reasoning

Does this Observer example survive a process crash with durable notifications?
Choose one answer. You can try again.

Answer and explanation

No; its subscribers and calls are in memory.

Cross-process recovery requires more mechanisms.

Name the responsibility before choosing the pattern

For Observer, describe the problem, the participating roles and the observable contract. Use the example as a starting point and test the boundaries identified in the trade-offs. A pattern name alone does not establish correctness or performance.

Return to the design-pattern guide to compare families, or apply the idea alongside the meaning and commit point of events.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Command Pattern →