The Observer Pattern is a design pattern used in Object-Oriented software development. It outlines a relationship between an object, known as the subject, and any number of other objects known as the observers, such that the observers are automatically notified when the state of the subject changes.
A more practical way to think of the Observer Pattern is by comparing it to those annoying “subscribe for updates” boxes that pop up on websites (not ours, of course.) By entering your email and clicking “submit” you are becoming an observer to the website. That is—when there is an update on the website you’ll be automatically notified via email, push message, SMS, or related means of communication.
The Observer Pattern Anatomy
The Observer Pattern design pattern is made of two primary parts: the Subject and the Observer. The subject is tasked with maintaining a list of which objects are observing it and communicating with these objects during a state change. Below is a brief outline of these objects and the methods required to provide base functionality required by the Observer Pattern.
The subject is a class that defines the object that’s at the center of all the attention. This might be a sensor module, a news publication, or a politician. The common thread is that change in these entities is monitored by other entities such that those observing the subject are dependent on it.
The role of public scrutiny and fame doesn’t come without responsibility, however; the Subject must implement some basic methods of communicating with its observers. Below are the bare minimum of methods any decent subject must implement to successfully serve its role in the Observer Pattern.
The subject is tasked with updating all observers when it undergoes a state change. The precise means by which this update occurs various by the implementation but remains consistent, and required, in concept.
The subject in the Observer Pattern must maintain a tally of which Observer objects are to be notified after a change in state. This tally can be a list, hash table, or any other form of reference collection deemed appropriate. The Subject must provide a means for Observers to register (think, subscribe) to be notified.
Just as the Subject must allow Observers to register to receive updates, the Subject must also provide a method by which Observers can be removed from receiving notification of state change (think, unsubscribe.)
I’ve always felt it odd that the namesake of the Observer Pattern is the dependant object. Nonetheless, the Observer is the component of this design pattern that is updated on system state change such that it can take appropriate action.
To successfully participate in the Observer Pattern, the Observer must implement a basic method to accept communication from the Subject. The specifics of how an Observer handles received communication varies but the acceptance is critical. Below is an outline of the method used for such a design.
When a Subject’s state changes, it initiates a sequence by which each Observer is sent notification. This line of communication is generally called from within a looping method in the Subject’s implementation of
updateObservers such that each Observer’s
update method is called. The details of this method vary based on use-case.
The Observer Pattern is one of the first design patterns I learned and one of the commonest patterns found in software design. There are a lot of great books on software design & programming that touch on the Observer, but the following resources are particularly useful:
- Headfirst Design Patterns: A Brain-Friendly Guide
- Design Patterns: Elements of Reusable Object-Oriented Software
- Game Programming Patterns
Each of these books has something unique to offer: the first; known as the breakthrough introduction. The second; a uniquely simplified and easily-digested presentation. The third; a contextualized discussion that may be more engaging to many readers.
The Observer Pattern is one of the simplest and most useful design patterns of which I am aware. It helps simplify the passing of data among system components—staying away from code smell by keeping things loosly coupled in line with SOFA and SOLID design principles. Some design patterns are more exotic and not necessarily pragmatic to be actively aware of to produce good code. The Observer Pattern is not one of these and can benefit anyone via its straight-forward implementation strategy and provided functionality.