An Intro to Observer Design in Pattern PHP

The Observer design pattern defines a one-to-many dependency between objects so that when an object state is changed, all of its dependents are notified and updated automatically and in this tutorial, you will see how to implement this pattern in PHP programming language the right way.

As an example of one-to-many relationship, we can think of a newspaper (one) that a lot of subscribers (many) are reading. As in the real-world when a piece of news comes out all subscribers are notified, in a code block based on the Observer pattern all dependent modules or let's say all observers are informed when the state of the subject they are observing changes.

For example, in the following code block we want to create a notification service which notifies subscribers when an update comes:

<?php
interface ObserverInterface
{
    public function update(SubjectInterface $subject);
}

interface SubjectInterface
{
    public function attach(ObserverInterface $observer);
    public function notify();
}

class Publisher implements SubjectInterface
{
    public $observers = [];
    public $name;

    public function __construct($name)
    {
        $this->name = $name;
        echo "$name is created as a publisher.\n\n";
    }

    public function attach(ObserverInterface $observer)
    {
        array_push($this->observers, $observer);
        echo "$observer->name is attached to the $this->name publisher\n";
    }

    public function notify()
    {
        echo "\n";
        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
    }
}

class Observer implements ObserverInterface
{
    public $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function update(SubjectInterface $publisher)
    {
        echo "An update is sent to $this->name from $publisher->name publisher\n";
    }
}

$publisherObj = new Publisher('Notification');

$publisherObj->attach(new Observer('Email Subscriber'));
$publisherObj->attach(new Observer('SocialMedia Subscriber'));
$publisherObj->attach(new Observer('SMS Subscriber'));

$publisherObj->notify();

First, let's run the code next what happens behind the scene is explained:

Notification is created as a publisher.

Email Subscriber is attached to the Notification publisher
SocialMedia Subscriber is attached to the Notification publisher
SMS Subscriber is attached to the Notification publisher

An update is sent to Email Subscriber from Notification publisher
An update is sent to SocialMedia Subscriber from Notification publisher
An update is sent to SMS Subscriber from Notification publisher

As you can see, first of all, a service called Notification is created as a publisher. Next, three different subscribers are created (Email, SocialMedia, and SMS) and finally, after calling the notify() method, an update message is sent to all subscribers.

In this implementation of the Observer design pattern, we created two interfaces called ObserverInterface and SubjectInterface which the first one dictates what methods the subscribers (observers) need to have and the latter defines attach() and notify() methods which will be implemented in the subject (publisher) class.

The Publisher class has two properties called $observers which is an array of the names of all observers and $name which holds the name of the publisher. In the constructor of this class, we assign the $name parameter to the $name property and print a message citing a publisher with a given name is created.

In the attach() method which accepts a parameter of ObserverInterface type, we add the newly-added observer to $observers property via PHP built-in function array_push() then print a related message. In the notify() method we need to notify all observers; so we call the update() method of Observer class (As the update() method needs to have a parameter of SubjectInterface type, we write $this which is related to Publisher class itself.)

In the Observer class, we need to assign value to the $name property which is done via its constructor. The only method of this class update() is tasked to show a message that an update is sent to the subscriber via publisher and this is how this design pattern functions.

by Behzad Moradi on 2019-08-12

Login to add your comment