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
Thank you for the contribution. It has been approved.
You can contact us on Discord.
[utopian-moderator]
Hey @therealsmat I am @utopian-io. I have just upvoted you!
Achievements
Suggestions
Get Noticed!
Community-Driven Witness!
I am the first and only Steem Community-Driven Witness. Participate on Discord. Lets GROW TOGETHER!
Up-vote this comment to grow my power and help Open Source contributions like this one. Want to chat? Join me on Discord https://discord.gg/Pc8HG9x