1
+ <?php
2
+
3
+ namespace DesignPatterns ;
4
+
5
+ /**
6
+ * strategy pattern
7
+ *
8
+ * Terminology:
9
+ * - Context
10
+ * - Strategy
11
+ * - Concrete Strategy
12
+ *
13
+ * Purpose:
14
+ * to separate strategies and to enable fast switching between them.
15
+ * also this pattern is a good alternative to inheritance (instead of having an abstract class that is extended)
16
+ *
17
+ * Examples:
18
+ * - sorting a list of objects, one strategy by date, the other by id
19
+ * - simplify unit testing: e.g. switching between file and in-memory storage
20
+ *
21
+ */
22
+
23
+ interface Comparator
24
+ {
25
+ /**
26
+ * @abstract
27
+ * @param object $a
28
+ * @param object $b
29
+ * @return bool
30
+ */
31
+ public function compare ($ a , $ b );
32
+ }
33
+
34
+ class ObjectCollection
35
+ {
36
+ private $ _elements ;
37
+ private $ _comparator ;
38
+
39
+ /**
40
+ * @param array $elements
41
+ */
42
+ public function __construct (array $ elements = array ())
43
+ {
44
+ $ this ->_elements = $ elements ;
45
+ }
46
+
47
+ /**
48
+ * @return array
49
+ */
50
+ public function sort ()
51
+ {
52
+ $ callback = array ($ this ->_comparator , 'compare ' );
53
+ uasort ($ this ->_elements , $ callback );
54
+
55
+ return $ this ->_elements ;
56
+ }
57
+
58
+ /**
59
+ * @param Comparator $comparator
60
+ * @return void
61
+ */
62
+ public function setComparator (Comparator $ comparator )
63
+ {
64
+ $ this ->_comparator = $ comparator ;
65
+ }
66
+ }
67
+
68
+ class IdComparator implements Comparator
69
+ {
70
+ public function compare ($ a , $ b )
71
+ {
72
+ if ($ a ['id ' ] == $ b ['id ' ]) {
73
+ return 0 ;
74
+ } else {
75
+ return $ a ['id ' ] < $ b ['id ' ] ? -1 : 1 ;
76
+ }
77
+ }
78
+ }
79
+
80
+ class DateComparator implements Comparator
81
+ {
82
+ public function compare ($ a , $ b )
83
+ {
84
+ $ aDate = strtotime ($ a ['date ' ]);
85
+ $ bDate = strtotime ($ b ['date ' ]);
86
+
87
+ if ($ aDate == $ bDate ) {
88
+ return 0 ;
89
+ } else {
90
+ return $ aDate < $ bDate ? -1 : 1 ;
91
+ }
92
+ }
93
+ }
94
+
95
+ $ elements = array (
96
+ array (
97
+ 'id ' => 2 ,
98
+ 'date ' => '2011-01-01 ' ,
99
+ ),
100
+ array (
101
+ 'id ' => 1 ,
102
+ 'date ' => '2011-02-01 '
103
+ )
104
+ );
105
+
106
+ $ collection = new ObjectCollection ($ elements );
107
+ $ collection ->setComparator (new IdComparator ());
108
+ $ collection ->sort ();
109
+
110
+ $ collection ->setComparator (new DateComparator ());
111
+ $ collection ->sort ();
0 commit comments