Oluwatosin Soremekun avatar

Design Patterns in PHP - Responsibility chaining

therealsmat

Published: 04 Mar 2018 › Updated: 04 Mar 2018Design Patterns in PHP - Responsibility chaining

Design Patterns in PHP - Responsibility chaining

What Will I Learn?

In this tutorial you will learn about the chaining pattern in php. You will also learn

  • The importance design patterns pattern
  • Popular projects that implement this pattern
  • An example implementation.

Requirements

To follow along in this tutorial, you should

  • have php installed on your machine
  • have a good understanding of classes (and objects) in php

Difficulty

  • Intermediate

Tutorial Contents

It is generally recommended to always write codes with a design pattern. It brings clarity and structure to your codes. It also makes it very easy to explain to someone who is working with or inspecting the code base.

Chances are that you already use some of these patterns, but don't know the name given to it. You might also not know some generally accepted practices using that pattern. In this tutorial, we'll be looking at the Chaining pattern, as used in php. What you'll learn from this tutorial will be influenced by my 5years+ experience with programming.

The way i like to look at chaining is, it makes me write code like i'm describing a thing. For instance, lets say i need to write an algorithm to exit my house everyday, i'll

  • check the lights
  • close the windows
  • lock the door
  • exit the house.

So i'll write a class and compose the above steps into methods like this;

class MyHouse {
     
    public function checkLights(){
        return $this;
    }

    public function closeWindows(){
        return $this;
    }

    public function lockDoors(){
        return $this;
    }

    public function exit(){
        echo "You have exited your house";
    }

}

Then to use the class,

<?php

class Controller {

    public function index(){

        $house = new MyHouse;

        $house->checkLights()->closeWindows()->lockDoors()->exit();

    }
}

The above example is very trivial, but it presents the basic idea.

As we can already notice, the main thing that makes chaining possible is, any method you want to be chained against must return an instance of an object; hence return $this;

Let's make a more realistic example.

Let us create a class for an SMS service so that we can easily send SMS' to our customers. We'll call it UtopianSMS.

UtopianSMS will need the following configurations;

  • API key
  • Email Address
  • Sender Name

As parameters, we will be needing

  • Recipients
  • Message
  • Sender Name (optional)

Step1

  • Create and initialize the UtopianSMS class
<?php

namespace therealsmat;

class UtopianSMS {

    /**
     * Stores the sms client key
     *
     * @var
     */
    private $apiKey;

    /**
     * Stores the account email address
     *
     * @var
     */
    private $email;

    /**
     * Stores the sender name
     *
     * @var
     */
    protected $senderName;


    /**
     * Mutator for ApiKey
     *
     * @param $key
     * @return mixed
     */
    public function setApiKey($key)
    {
        return $this->apiKey = $key;
    }

    /**
     * Mutator for account email
     *
     * @param $email
     * @return mixed
     */
    public function setEmail($email)
    {
        return $this->email = $email;
    }

    /**
     * Mutator for sender name
     *
     * @param $name
     * @return mixed
     */
    public function setSender($name)
    {
        return $this->senderName = trim($name);
    }
}

Step 2

  • Create the methods we need to send mails
/**
     * Mutator for sender name
     *
     * @param $name
     * @return mixed
     */
    public function setSender($name)
    {
        return $this->senderName = trim($name);
    }

    /**
     * Set the message to be sent
     *
     * @param $message
     * @return UtopianSMS
     */
    public function message($message)
    {
        $this->message = trim($message);
        return $this;
    }

    /**
     * Add recipients
     *
     * @param $recipients
     * @return $this
     */
    public function to($recipients)
    {
        if (is_array($recipients)) {
            $this->receipents = $recipients;
        } else {
            $this->receipents = explode(',', $recipients);
        }

        return $this;
    }

    public function send()
    {
        #. Add your protocol for sending the sms
        #.. Most likely, perform an http request...
    }

Step 3
Lets consume our class.

  • Create a controller
class Controller {

    public function index()
    {
        $utopian = new UtopianSMS();

        $apiKey = 'dhjfhj';
        $senderName = 'therealsmat';
        $email = 'hello@example.com';

        $utopian->setApiKey($apiKey)
                ->setSender($senderName)
                ->setEmail($email);

        $recipients = ['09098765431'];

        $utopian->message('Hello there, thanks for signing up!')
                ->to($recipients)
                ->send();
    }
}

Now we have successfully implemented chaining. I hope this helps you.

Full Codes

<?php

namespace therealsmat;

class UtopianSMS {

    /**
     * Stores the sms client key
     *
     * @var
     */
    private $apiKey;

    /**
     * Stores the account email address
     *
     * @var
     */
    private $email;

    /**
     * Stores the sender name
     *
     * @var
     */
    protected $senderName;

    /**
     * Stores the message to be sent
     *
     * @var
     */
    private $message;

    /**
     * SMS Recipients
     *
     * @var array
     */
    private $receipents = [];


    /**
     * Mutator for ApiKey
     *
     * @param $key
     * @return mixed
     */
    public function setApiKey($key)
    {
        return $this->apiKey = $key;
    }

    /**
     * Mutator for account email
     *
     * @param $email
     * @return mixed
     */
    public function setEmail($email)
    {
        return $this->email = $email;
    }

    /**
     * Mutator for sender name
     *
     * @param $name
     * @return mixed
     */
    public function setSender($name)
    {
        return $this->senderName = trim($name);
    }

    /**
     * Set the message to be sent
     *
     * @param $message
     * @return UtopianSMS
     */
    public function message($message)
    {
        $this->message = trim($message);
        return $this;
    }

    /**
     * Add recipients
     *
     * @param $recipients
     * @return $this
     */
    public function to($recipients)
    {
        if (is_array($recipients)) {
            $this->receipents = $recipients;
        } else {
            $this->receipents = explode(',', $recipients);
        }

        return $this;
    }

    public function send()
    {
        #. Add your protocol for sending the sms
        #.. Most likely, perform an http request...
    }
}

class Controller {

    public function index()
    {
        $utopian = new UtopianSMS();

        $apiKey = 'dhjfhj';
        $senderName = 'therealsmat';
        $email = 'hello@example.com';

        $utopian->setApiKey($apiKey)
                ->setSender($senderName)
                ->setEmail($email);

        $recipients = ['09098765431'];

        $utopian->message('Hello there, thanks for signing up!')
                ->to($recipients)
                ->send();
    }
}

Take a look at my project https://github.com/therealSMAT/laravel-ebulksms. Chaining was used almost throughout the project.



Posted on Utopian.io - Rewarding Open Source Contributors

Leave Design Patterns in PHP - Responsibility chaining to:

Written by

Software Developer. Little guy, but that's not all i'm going to be

Read more #utopian-io posts


Best Posts From Oluwatosin Soremekun

We have not curated any of therealsmat's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From Oluwatosin Soremekun