Skip to content

Commit dddfdf6

Browse files
committed
88 - Added undo example for command pattern
1 parent 4904def commit dddfdf6

File tree

5 files changed

+141
-2
lines changed

5 files changed

+141
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace DesignPatterns\Behavioral\Command;
4+
5+
/**
6+
* This concrete command tweaks receiver to add current date to messages
7+
* invoker just knows that it can call "execute".
8+
*/
9+
class AddMessageDateCommand implements CommandInterface, UndoableCommandInterface
10+
{
11+
/**
12+
* @var Receiver
13+
*/
14+
protected $output;
15+
16+
/**
17+
* Each concrete command is built with different receivers.
18+
* There can be one, many or completely no receivers, but there can be other commands in the parameters.
19+
*
20+
* @param Receiver $console
21+
*/
22+
public function __construct(Receiver $console)
23+
{
24+
$this->output = $console;
25+
}
26+
27+
/**
28+
* Execute and make receiver to enable displaying messages date.
29+
*/
30+
public function execute()
31+
{
32+
// sometimes, there is no receiver and this is the command which
33+
// does all the work
34+
$this->output->enableDate();
35+
}
36+
37+
/**
38+
* Undo the command and make receiver to disable displaying messages date.
39+
*/
40+
public function undo()
41+
{
42+
// sometimes, there is no receiver and this is the command which
43+
// does all the work
44+
$this->output->disableDate();
45+
}
46+
}

Behavioral/Command/Receiver.php

+30-1
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,40 @@
77
*/
88
class Receiver
99
{
10+
private $enableDate = false;
11+
12+
private $output = array();
13+
1014
/**
1115
* @param string $str
1216
*/
1317
public function write($str)
1418
{
15-
echo $str;
19+
if ($this->enableDate) {
20+
$str .= ' ['.date('Y-m-d').']';
21+
}
22+
23+
$this->output[] = $str;
24+
}
25+
26+
public function getOutput()
27+
{
28+
return implode("\n", $this->output);
29+
}
30+
31+
/**
32+
* Enable receiver to display message date.
33+
*/
34+
public function enableDate()
35+
{
36+
$this->enableDate = true;
37+
}
38+
39+
/**
40+
* Disable receiver to display message date.
41+
*/
42+
public function disableDate()
43+
{
44+
$this->enableDate = false;
1645
}
1746
}

Behavioral/Command/Tests/CommandTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ protected function setUp()
3030
public function testInvocation()
3131
{
3232
$this->invoker->setCommand(new HelloCommand($this->receiver));
33-
$this->expectOutputString('Hello World');
3433
$this->invoker->run();
34+
$this->assertEquals($this->receiver->getOutput(), 'Hello World');
3535
}
3636
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace DesignPatterns\Behavioral\Command\Tests;
4+
5+
use DesignPatterns\Behavioral\Command\AddMessageDateCommand;
6+
use DesignPatterns\Behavioral\Command\HelloCommand;
7+
use DesignPatterns\Behavioral\Command\Invoker;
8+
use DesignPatterns\Behavioral\Command\Receiver;
9+
use PHPUnit_Framework_TestCase;
10+
11+
/**
12+
* UndoableCommandTest has the role of the Client in the Command Pattern.
13+
*/
14+
class UndoableCommandTest extends PHPUnit_Framework_TestCase
15+
{
16+
/**
17+
* @var Invoker
18+
*/
19+
protected $invoker;
20+
21+
/**
22+
* @var Receiver
23+
*/
24+
protected $receiver;
25+
26+
protected function setUp()
27+
{
28+
$this->invoker = new Invoker();
29+
$this->receiver = new Receiver();
30+
}
31+
32+
public function testInvocation()
33+
{
34+
$this->invoker->setCommand(new HelloCommand($this->receiver));
35+
$this->invoker->run();
36+
$this->assertEquals($this->receiver->getOutput(), 'Hello World');
37+
38+
$messageDateCommand = new AddMessageDateCommand($this->receiver);
39+
$messageDateCommand->execute();
40+
41+
$this->invoker->run();
42+
$this->assertEquals($this->receiver->getOutput(), "Hello World\nHello World [".date('Y-m-d').']');
43+
44+
$messageDateCommand->undo();
45+
46+
$this->invoker->run();
47+
$this->assertEquals($this->receiver->getOutput(), "Hello World\nHello World [".date('Y-m-d')."]\nHello World");
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace DesignPatterns\Behavioral\Command;
4+
5+
/**
6+
* Interface UndoableCommandInterface.
7+
*/
8+
interface UndoableCommandInterface
9+
{
10+
/**
11+
* This method is used to undo change made by command execution
12+
* The Receiver goes in the constructor.
13+
*/
14+
public function undo();
15+
}

0 commit comments

Comments
 (0)