SnapShooter Backups Server, Database, Application and Laravel Backups - Get fully protected with SnapShooter

Understanding Design Patterns - Command

Encapsulates a request as an object, thereby letting you parameterize other objects with different requests, queue or log requests, and support undoable operations.

Battles are meant to be won, and no battle can be won without a good plan or strategy. Most battles that are lost are those where the commander orders his men into the battlefield without any plan or, worse, without the capacity to command his men while they are in battle. The result is havoc with every man fighting for himself instead of the group fighting as a group and protecting each other. A carefully laid out plan, with each man knowing his position and what to do at the right time, is the perfect battle plan. Have you ever thought of how battlefield plans are made? If we simulated it in our code, do you think it would be complicated or interesting? As it turns out, it is quite interesting, and if programming was used in battle, it would be the simplest thing to win one battle after another.

In this chapter, we will see how battle plans are made with programming using Command Pattern.

In a typical Command Pattern, there are five elements. They are command interface, client, receiver, invoker, and concrete command.

We will explain them in detail later in the chapter.

But first, let us complete the code for our battle plan:

interface Command
{
    public function execute();
}
 
class Gunner
{
   public function fire()
   {
        echo 'Fire in the hole';
   }
}
 
class GunnerFireCommand implements Command
{
    private $_gunner = null;
    public function _construct(Gunner $gunner)
    {
       $this->_gunner = $gunner;
    }
 
    public function execute()
    {
           $this->_gunner->fire();
    }
}
 
class BattlePlan
{
    public $commandsWithCodeNames = array();
    public function setCommand($codeName, Command $command)
    {
        $this->commandsWithCodeNames[$codeName] = $command;
    }
 
    public function executeCommand($codeName)
    {
        $command = $this->commandsWithCodeNames[$codeName];
        $command->execute();
    }
}
 
// Commander's code
$peter = new Gunner();
$gunnerFireCommand = new GunnerFireCommand($peter);
$planA = new BattlePlan();
$planA->setCommand('planA', $gunnerFireCommand);

Now let us use as an example the four elements in the Command Pattern:

Let us rework the code.

  • Command interface: it defines a common method, so all concrete command classes have to implement it.
  • Client: it is responsible for creating concrete command objects and receiver objects. In our battlefield example, the commander is the client.
  • Invoker: it contains concrete command objects and call the execute() method at some point of time. Please note that it holds concrete command objects by its interface(Command interface), it does not actually know the exact type of objects it holds (Programming to abstraction), so only execute() method of concrete command objects is exposed to it. In our battlefield example, the battle plan is the invoker.
  • Receiver: it performs the specific tasks. In our battlefield example, Gunner is the receiver.
  • Concrete Command: this class implements the Command interface and implement the execute() method. Its purpose is to encapsulate the request as an object. To accomplish this, it binds a set of receiver’s actions together and exposes the execute()method to the outside. In our battlefield example, GunnerFireCommand is a concrete command.

In our battlefield example, by using Command Pattern, we encapsulate a request (fire()method of Gunner class) as an object (GunnerFireCommand). It lets us parameterize other objects with different requests, queue, or log requests (commander is able to make different battle plans with different commands, for example, he can make a command to request a sniper and a gunner to attack together).

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.