File tree Expand file tree Collapse file tree 3 files changed +103
-0
lines changed
Tests/ChainOfResponsibilities Expand file tree Collapse file tree 3 files changed +103
-0
lines changed Original file line number Diff line number Diff line change
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
+ }
Original file line number Diff line number Diff line change
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
+ }
Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments