TailTemplate Build stunning websites faster with our pre-designed Tailwind CSS templates

Understanding Design Patterns - Observer

Defines a one-to-many dependency between objects so that when on object changes state, all of its dependents are notified and updated automatically.

Mary just became a new Mom! Like all new mothers, she is very excited about her new baby boy, Nathan. Life just turned very rewarding but also challenging for Mary. As a new mom she is experiencing the joys and challenges of caring for a new born baby. The baby is a light sleeper and easily gets disturbed by small noises grown-ups make. So to make sure the baby is well rested and happy, Mary and her husband have decided to turn their guest room into a nursery. This is perfect for the baby with a little sacrifice on Mary's end because she has to check on the baby several times at night to make sure everything is fine.

This is how it looks like from the coding point of view:

$mary   = new Mother();
$nathan = new Son();
$time   = date('H');
// wake up at 1am , 3am and 5am
if ($time=='01' || $time=='03' || $time=='05') {
    $mary->wakeUp();
    if ($nathan->isCrying()) {
        $mary->comfortBaby();
    }
}

The baby is doing fine in his new nursery, but her husband noticed that Mary is looking a little tired. “Honey, why do you look so tired this morning?” he asked his wife. Mary explained that she has to make several trips to the baby's room last night to make sure that the baby is fine. Obviously, this nightly routine of getting up at odd hours to check on little Nathan is becoming exhausting for Mary. She is losing sleep and feels tired in the morning. It will only be a matter of time until Mary will be sleep lagged and too exhausted during the day to take care of the baby. This can take all the fun out of having a new baby. She knows that she needs to find a way to improve this because she can get stressed and even sick. Luckily, her good friend Rose came to visit and introduced her to a tool called baby audio monitor. The audio monitor is placed inside the baby's room, and the moment little Nathan cries or makes a fuss, the audio monitor gives out a sound to tell Mary that her baby needs her. Mary was so happy with this new tool because instead of pro-actively waking up to check on the baby, she can sleep soundly and only wake up to check on Nathan if the monitor tells her she needs to. Without knowing, Mary has used the Observer Pattern here. Let us see how it applies. With the help of the baby audio monitor, Mary registered herself as an observer of the subject (Nathan). Whenever the subject’s state changes (Nathan cries or makes any noise), the observer(Mary) is notified automatically.

Let us rework the code.

First, we need to create two interfaces. The Observable interface, which is the interface of the Subject, and the Observer interface, which is the interface of Observer.

Observable:

interface Observable
{
    public function  registerObserver(Observer $o);
    public function  removeObserver(Observer $o);
    public function  notifyObservers();
}

Observer:

interface Observer
{
    public function update();
}

Then we need to modify Son class to implement Observable interface:

class Son implements Observable
{
    private $_observers = array();
    private $_isCry = false;
    public function registerObserver(Observer $o)
    {
        $this->_observers[] = $o;
    }
 
    public function removeObserver(Observer $o)
    {
        foreach($this->_observers as $index=>$value) {
            if ($value==$o) {
                unset($this->_observers[$index]);
            }
        }
    }
 
    public function notifyObservers()
    {
        foreach($this->_observers as $observer) {
            $this->_observer->update();
        }
    }
 
    public function cry()
    {
        $this->_isCry = true;
        $this->notifyObservers();
    }
 
    public function isCry()
    {
        return $this->_isCry;
    }
}

And Mother class needs to implement Observer interface:

class Mother implements Observer
{
    public function update()
    {
        $this->wakeUp();
        $this->comfortBaby();
    }
 
    public function wakeUp()
    {
        echo 'Wake up at once!';
    }
 
    public function comfortBaby()
    {
        echo 'Baby do not cry.';
    }
}

Second, let us register Mary as an observer of Nathan at run time.

$mary   = new Mother();
$nathan = new Son();
$nathan->registerObserver($mary);

With the help of the Observer Pattern, Mary has improved her daily routine and is now enjoying mommy life more. Some nights, she does not even have to wake up at all. As Nathan grows up, Mary w

ill certainly no longer need to use the baby audio monitor. That is when she can remove herself as an observer of her son:

$nathan->removeObserver($mary);

The end

Hopefully this simple tutorial helped you with your development. If you like our post, please follow us on Twitter and help spread the word. We need your support to continue. If you have questions or find our mistakes in above tutorial, do leave a comment below to let us know.