Observer Design Pattern

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

Share

Leave a Reply

Your email address will not be published. Required fields are marked *