Skip to content

Commit 5ef810f

Browse files
author
Trismegiste
committed
add the generic handler and the request classes
1 parent fc781c8 commit 5ef810f

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed

ChainOfResponsibilities/Handler.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/*
4+
* DesignPatternPHP
5+
*/
6+
7+
namespace DesignPatterns\ChainOfResponsibilities;
8+
9+
/**
10+
* Handler is a generic handler in the chain of responsibilities
11+
*/
12+
abstract class Handler implements KeyValueStorage
13+
{
14+
15+
protected $successor = null;
16+
17+
/**
18+
* Append a responsibility to the end of chain
19+
*
20+
* A prepend method could be done with the same spirit
21+
*
22+
* You could also send the successor in the contructor but in PHP it is a
23+
* bad idea because you have to remove the type-hint of the parameter because
24+
* the last handler has a null successor.
25+
*
26+
* And if you override the contructor, your Handler can no longer have a
27+
* successor. One solution is to provide a NullObject (see pattern)
28+
*/
29+
final public function append(Handler $handler)
30+
{
31+
if (is_null($this->successor)) {
32+
$this->successor = $handler;
33+
} else {
34+
$this->successor->append($handler);
35+
}
36+
}
37+
38+
/**
39+
* Handle the request.
40+
*
41+
* This approach by using a template method pattern ensures you that
42+
* each subclass will not forget to call the successor. Beside, the returned
43+
* boolean value indicates you if the request have been processed or not.
44+
*/
45+
final public function handle(Request $req)
46+
{
47+
$processed = $this->processing($req);
48+
if (!$processed) {
49+
if (!is_null($this->successor)) {
50+
$processed = $this->successor->handle($req);
51+
}
52+
}
53+
54+
return $processed;
55+
}
56+
57+
abstract protected function processing(Request $req);
58+
}

ChainOfResponsibilities/Request.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* DesignPatternPHP
5+
*/
6+
7+
namespace DesignPatterns\ChainOfResponsibilities;
8+
9+
/**
10+
* Request is a request which goes throught the chain of responsibilities.
11+
*
12+
* About the request : Sometimes, you don't need an object, just an integer or
13+
* an array. But in this case of a full example, I've made a class to illustrate
14+
* this important idea in the CoR (Chain of Responsibilities). In real world,
15+
* I recommand to always use a class, even a \stdClass if you want, it proves
16+
* to be more adaptative because a single handler doesn't know much about the
17+
* outside world and it is more difficult if, one day, you want add some
18+
* criterion in a decision process.
19+
*/
20+
class Request
21+
{
22+
23+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* DesignPatternPHP
5+
*/
6+
7+
namespace DesignPatterns\Tests\ChainOfResponsibilities;
8+
9+
use DesignPatterns\ChainOfResponsibilities\Request;
10+
11+
/**
12+
* ChainTest tests the CoR
13+
*/
14+
class ChainTest extends \PHPUnit_Framework_TestCase
15+
{
16+
17+
public function testProcess()
18+
{
19+
20+
}
21+
22+
}

0 commit comments

Comments
 (0)