Observer Design Pattern
The Observer Design Pattern defines a one to many dependency between objects such that when one object changes state all of its dependants are notified and updated automatically.
The observer design pattern is a really simply, yet incredibly useful pattern. You’ll already be familiar with how it works. Imagine you want to be kept informed of the weather updates for your area (or if you’re in South Africa – Eskom se push!). You download your favourite weather app and subscribe with your area in it. Now each time they get a weather update they push this notification to your phone so you get an alert. When you decide you no longer want these notifications you unsubscribe and you’ll no longer receive these push notifications.
The Observer Design Pattern works in the same way, but at the class level. Its a great example of loosely coupled design between objects.
How it works
We have a subject object which is the object who’s state changes we’re interested in and the observer objects who subscribe to the subject to receive updates about its state changes.
In our image above and keeping with our weather example imagine the Subject is an object which receives weather information from a weather satellite. Further imagine that the Observer objects are objects which require those state changes, eg, a display object to display the latest data on a screen, a notification objects to send out notices and maybe a logger object to log data to some place.
Each observer subscribes to the subject and when the subject’s state changes it loops over the list of subscribed observers and calls a method to update them.
This can take place in various ways. For instance, the subject could simply notify the observers that something has changed and the observers could then call the Subject to get data that it needs. This might be a good way of doing thing if there is a large amount of data and each observer only requires a small subset of that data.
Another way could be that the Subject sends a payload with directly when it updates the observers with all of the information in the payload.
Example Code
In our PHP Observer Design Pattern example implementation we want to keep things super simple so we’ll be passing the data with the update method.
We use interfaces for our Subject and Observers. One thing to remember is that each of these classes do “other stuff” aside from implementing the Observer Design Pattern.
The Subject
The Subject interface has three methods: subscribe, unsubscribe and notify.
The observer’s will call subscribe if they want to subscribe to this Subject. The subject will then add that observer into its list of observer’s to notify about updates. If an observer no longer wishes to receive these notifications it can call unsubscribe on the Subject.
When the state changes in the subject it can internally call the notify method which will notify the observers. Note: in our example we’re calling notify directly on the subject from external to the object. This is not usually how things work, its simply for this example.
interface SubjectInterface
{
public function subscribe($object);
public function unsubscribe($object);
public function notify();
}
class Subject implements SubjectInterface
{
private $observers = [];
public function subscribe($object)
{
if ( ! in_array($object, $this->observers)) {
$this->observers[] = $object;
}
}
public function unsubscribe($object)
{
$index = array_search($object, $this->observers);
if ($index !== false) {
array_splice($this->observers, $index, 1);
}
}
public function notify()
{
foreach ($this->observers as $observer) {
$observer->update();
}
}
// OTHER METHODS HERE...
}
The Observers
The observer implements the ObserverInterface. The observer interface has a single method called update. This update method is what will get called by the Subject when its state changes.
interface ObserverInterface
{
public function update();
}
class ObserverOne implements ObserverInterface
{
public $name = "ObserverOne";
public function update() {
print "\r\nupdate called in ObserverOne\r\n";
}
}
class ObserverTwo implements ObserverInterface
{
public $name = "ObserverTwo";
public function update() {
print "\r\nupdate called in ObserverTwo\r\n";
}
}
And that’s a wrap. We’ve implemented a very simple Observer Design Pattern in PHP. You can now easily subscribe as many new objects to the to Subject as you may need in the future without needing to change the original code. This pattern helps us with the O in the SOLID design principle. The O means that code should be Open for extension but closed to modification.
You can download the example code from github: https://github.com/jsmcm/blogs.php.observer-design-pattern
John, a seasoned Freelance Full Stack Developer based in South Africa, specialises in delivering bespoke solutions tailored to your needs. With expertise in PHP, Laravel, Vue3, and Nuxt3, I am equipped to tackle any project, ensuring robust, scalable, and cutting-edge outcomes.
My comprehensive skill set enables me to provide exceptional freelance services both remotely and in person. Whether you’re seeking to develop an innovative application or require meticulous refinement of existing systems, I am dedicated to elevating your digital presence through unparalleled technical prowess and strategic development methodologies. Let’s connect to transform your vision into reality.