Before we start, you might ask:

What is a design pattern?

Design pattern is a general solution to particular problem that is occurring commonly. However this is not an already implemented source code (you’ll have to do that yourself). It is not an already finished design either. You can incorporate design patterns into your application design.

It formalizes best practices and describes interactions between objects and classes. Basically it is a template for how to solve a problem.

If you want to get a better description of what a design pattern is, you can read about it on Wikipedia

Observer pattern

It is a one-to-many push type design pattern, in which an object (“Subject”) maintains a list of dependants (“observers”). Once the subject changes state, it automatically notifies each observer with its new state.

You can think of it as a mailing list. Mailing list is the subject, you attach to it by sending in your e-mail address. But there can be many subscribers - Observer pattern does not limit the number of observers.

When there is a new email, the state has changed and the server emails it to each of the subscribers, including you!

Example

Let’s build our own simple application that uses the Observer pattern. In this example we’re going to use PHP.

There will be at least 2 classes - one for the Subject, one for the Observer.

The Subject will have to have at least these three methods:

  • Attach - a method that the observers will use to register
  • Detach - observers may want to unregister
  • Notify - This will change subject’s state

As for the Observer, we can get away with this single method:

  • Notify - Notification method, which will be called by the subject

Ok, let’s start coding! Let’s start by creating a Subject class:

<?php
// Subject.php
class Subject {
    private $observers = array(); // We will store observers here

    public function attach($observer) {
        if(!in_array($observer, $this->observers)) { // Make sure we don't add an observer twice
            $this->observers[] = $observer; // Add the observer
            return true;
        } else {
            return false; // Observer was not added
        }
    }

    public function detach($observer) {
        if(!in_array($observer, $this->observers)) { // Make sure the observer is registered
            return false;
        } else {
            $key = array_search($observer, $this->observers); // Find observer's key
            unset($this->observers[$key]); // Remove the observer
            $this->observers = array_values($this->observers); // Reindex the observer array, as unset leaves a gap
            return true;
        }
    }

    public function notify($message) {
        foreach($this->observers as $observer) { // Notify each observer
            $observer->notify($message); // Dispatch the message to each observer
        }
    }
};

Ok, we’ve implemented our Subject class. Observers will register through attach method and unregister through detach method. Notifications will be sent with notify method.

Now let’s build our Observer class:

<?php
// Observer.php
class Observer {
    public function notify($message) {
        echo "I have received a message: \r\n";
        var_dump($message); // Just print out any information it may contain: strings, numbers, objects...
        echo "END OF MESSAGE\r\n";
    }
};

Our Observer class only needs notify method, which will output all received messages.

And lastly, let’s create our demo program that makes use of these classes:

<?php
// main.php
require_once('Subject.php');
require_once('Observer.php');

$subject = new Subject(); // Create a Subject

// Let's try to change state. It should not output anything as it doesn't have any observers registered
$subject->notify('This shall not be read!');

// Let's create an Observer, register it and send another notification
$observer = new Observer(); // Create an Observer
$subject->attach($observer); // Register Observer to the Subject
$subject->notify('Can you see me?'); // Send notification to the Observer

If we run this, we should see Can you see me? text. If you do - good work! Now you know the Observer pattern.

I’ve created a Github repository with complete code from this article.