File tree Expand file tree Collapse file tree 9 files changed +384
-0
lines changed Expand file tree Collapse file tree 9 files changed +384
-0
lines changed Original file line number Diff line number Diff line change @@ -41,6 +41,7 @@ The patterns can be structured in roughly three different categories. Please cli
41
41
* [ Mediator] ( Mediator ) [ :notebook : ] ( http://en.wikipedia.org/wiki/Mediator_pattern )
42
42
* [ NullObject] ( NullObject ) [ :notebook : ] ( http://en.wikipedia.org/wiki/Null_Object_pattern )
43
43
* [ Observer] ( Observer ) [ :notebook : ] ( http://en.wikipedia.org/wiki/Observer_pattern )
44
+ * [ Specification] ( Specification ) [ :notebook : ] ( http://en.wikipedia.org/wiki/Specification_pattern )
44
45
* [ State] ( State ) [ :notebook : ] ( http://en.wikipedia.org/wiki/State_pattern )
45
46
* [ Strategy] ( Strategy ) [ :notebook : ] ( http://en.wikipedia.org/wiki/Strategy_pattern )
46
47
* [ TemplateMethod] ( TemplateMethod ) [ :notebook : ] ( http://en.wikipedia.org/wiki/Template_method_pattern )
Original file line number Diff line number Diff line change
1
+ <?php
2
+ namespace DesignPatterns \Specification ;
3
+
4
+ /**
5
+ * An abstract specification allows the creation of wrapped specifications
6
+ */
7
+ abstract class AbstractSpecification implements SpecificationInterface
8
+ {
9
+ /**
10
+ * Checks if given item meets all criteria
11
+ *
12
+ * @param Item $item
13
+ *
14
+ * @return bool
15
+ */
16
+ public function isSatisfiedBy (Item $ item )
17
+ {
18
+ }
19
+
20
+ /**
21
+ * Creates a new logical AND specification
22
+ *
23
+ * @param SpecificationInterface $spec
24
+ *
25
+ * @return SpecificationInterface
26
+ */
27
+ public function plus (SpecificationInterface $ spec )
28
+ {
29
+ return new Plus ($ this , $ spec );
30
+ }
31
+
32
+ /**
33
+ * Creates a new logical OR composite specification
34
+ *
35
+ * @param SpecificationInterface $spec
36
+ *
37
+ * @return SpecificationInterface
38
+ */
39
+ public function either (SpecificationInterface $ spec )
40
+ {
41
+ return new Either ($ this , $ spec );
42
+ }
43
+
44
+ /**
45
+ * Creates a new logical NOT specification
46
+ *
47
+ * @return SpecificationInterface
48
+ */
49
+ public function not ()
50
+ {
51
+ return new Not ($ this );
52
+ }
53
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+ namespace DesignPatterns \Specification ;
3
+
4
+ /**
5
+ * A logical AND specification
6
+ */
7
+ class Either extends AbstractSpecification
8
+ {
9
+
10
+ protected $ left ;
11
+ protected $ right ;
12
+
13
+ /**
14
+ * A composite wrapper of two specifications
15
+ *
16
+ * @param SpecificationInterface $left
17
+ * @param SpecificationInterface $right
18
+
19
+ */
20
+ public function __construct (SpecificationInterface $ left , SpecificationInterface $ right )
21
+ {
22
+ $ this ->left = $ left ;
23
+ $ this ->right = $ right ;
24
+ }
25
+
26
+ /**
27
+ * Returns the evaluation of both wrapped specifications as a logical AND
28
+ *
29
+ * @param Item $item
30
+ *
31
+ * @return bool
32
+ */
33
+ public function isSatisfiedBy (Item $ item )
34
+ {
35
+ return $ this ->left ->isSatisfiedBy ($ item ) || $ this ->right ->isSatisfiedBy ($ item );
36
+ }
37
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+ namespace DesignPatterns \Specification ;
3
+
4
+ /**
5
+ * An trivial item
6
+ */
7
+ class Item
8
+ {
9
+ protected $ price ;
10
+
11
+ /**
12
+ * An item must have a price
13
+ *
14
+ * @param int $price
15
+
16
+ */
17
+ public function __construct ($ price )
18
+ {
19
+ $ this ->price = $ price ;
20
+ }
21
+
22
+ /**
23
+ * Get the items price
24
+ *
25
+ * @return int
26
+ */
27
+ public function getPrice ()
28
+ {
29
+ return $ this ->price ;
30
+ }
31
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+ namespace DesignPatterns \Specification ;
3
+
4
+ /**
5
+ * A logical Not specification
6
+ */
7
+ class Not extends AbstractSpecification
8
+ {
9
+
10
+ protected $ spec ;
11
+
12
+ /**
13
+ * Creates a new specification wrapping another
14
+ *
15
+ * @param SpecificationInterface $spec
16
+
17
+ */
18
+ public function __construct (SpecificationInterface $ spec )
19
+ {
20
+ $ this ->spec = $ spec ;
21
+ }
22
+
23
+ /**
24
+ * Returns the negated result of the wrapped specification
25
+ *
26
+ * @param Item $item
27
+ *
28
+ * @return bool
29
+ */
30
+ public function isSatisfiedBy (Item $ item )
31
+ {
32
+ return !$ this ->spec ->isSatisfiedBy ($ item );
33
+ }
34
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+ namespace DesignPatterns \Specification ;
3
+
4
+ /**
5
+ * A logical AND specification
6
+ */
7
+ class Plus extends AbstractSpecification
8
+ {
9
+
10
+ protected $ left ;
11
+ protected $ right ;
12
+
13
+ /**
14
+ * Creation of a locical AND of two specifications
15
+ *
16
+ * @param SpecificationInterface $left
17
+ * @param SpecificationInterface $right
18
+
19
+ */
20
+ public function __construct (SpecificationInterface $ left , SpecificationInterface $ right )
21
+ {
22
+ $ this ->left = $ left ;
23
+ $ this ->right = $ right ;
24
+ }
25
+
26
+ /**
27
+ * Checks if the composite AND of specifications passes
28
+ *
29
+ * @param Item $item
30
+ *
31
+ * @return bool
32
+ */
33
+ public function isSatisfiedBy (Item $ item )
34
+ {
35
+ return $ this ->left ->isSatisfiedBy ($ item ) && $ this ->right ->isSatisfiedBy ($ item );
36
+ }
37
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+ namespace DesignPatterns \Specification ;
3
+
4
+ /**
5
+ * A specification to check an Item is priced between min and max
6
+ */
7
+ class PriceSpecification extends AbstractSpecification
8
+ {
9
+ protected $ maxPrice ;
10
+ protected $ minPrice ;
11
+
12
+ /**
13
+ * Sets the optional maximum price
14
+ *
15
+ * @param int $maxPrice
16
+ */
17
+ public function setMaxPrice ($ maxPrice )
18
+ {
19
+ $ this ->maxPrice = $ maxPrice ;
20
+ }
21
+
22
+ /**
23
+ * Sets the optional minimum price
24
+ *
25
+ * @param int $minPrice
26
+ */
27
+ public function setMinPrice ($ minPrice )
28
+ {
29
+ $ this ->minPrice = $ minPrice ;
30
+ }
31
+
32
+ /**
33
+ * Checks if Item price falls between bounds
34
+ *
35
+ * @param Item $item
36
+ *
37
+ * @return bool
38
+ */
39
+ public function isSatisfiedBy (Item $ item )
40
+ {
41
+ if ( !empty ($ this ->maxPrice ) && $ item ->getPrice () > $ this ->maxPrice ) {
42
+ return false ;
43
+ }
44
+ if ( !empty ($ this ->minPrice ) && $ item ->getPrice () < $ this ->minPrice ) {
45
+ return false ;
46
+ }
47
+
48
+ return true ;
49
+ }
50
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+ namespace DesignPatterns \Specification ;
3
+
4
+ /**
5
+ * An interface for a specification
6
+ */
7
+ interface SpecificationInterface
8
+ {
9
+ /**
10
+ * A boolean evaluation indicating if the object meets the specification
11
+ *
12
+ * @param Item $item
13
+ *
14
+ * @return bool
15
+ */
16
+ public function isSatisfiedBy (Item $ item );
17
+
18
+ /**
19
+ * Creates a logical AND specification
20
+ *
21
+ * @param SpecificationInterface $spec
22
+
23
+ */
24
+ public function plus (SpecificationInterface $ spec );
25
+
26
+ /**
27
+ * Creates a logical OR specification
28
+ *
29
+ * @param SpecificationInterface $spec
30
+
31
+ */
32
+ public function either (SpecificationInterface $ spec );
33
+
34
+ /**
35
+ * Creates a logical not specification
36
+ */
37
+ public function not ();
38
+ }
You can’t perform that action at this time.
0 commit comments