You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: specification/README.md
+43-25Lines changed: 43 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,36 +9,46 @@ tags:
9
9
---
10
10
11
11
## Also known as
12
+
12
13
Filter, Criteria
13
14
14
15
## Intent
15
-
Specification pattern separates the statement of how to match a
16
-
candidate, from the candidate object that it is matched against. As well as its
17
-
usefulness in selection, it is also valuable for validation and for building to
18
-
order.
16
+
17
+
Specification pattern separates the statement of how to match a candidate, from the candidate object
18
+
that it is matched against. As well as its usefulness in selection, it is also valuable for
19
+
validation and for building to order.
19
20
20
21
## Explanation
21
22
22
23
Real world example
23
24
24
-
> There is a pool of different creatures and we often need to select some subset of them.
25
-
> We can write our search specification such as "creatures that can fly", "creatures heavier than 500 kilograms", or as a combination of other search specifications, and then give it to the party that will perform the filtering.
25
+
> There is a pool of different creatures and we often need to select some subset of them. We can
26
+
> write our search specification such as "creatures that can fly", "creatures heavier than 500
27
+
> kilograms", or as a combination of other search specifications, and then give it to the party that
28
+
> will perform the filtering.
26
29
27
30
In Plain Words
28
31
29
-
> Specification pattern allows us to separate the search criteria from the object that performs the search.
32
+
> Specification pattern allows us to separate the search criteria from the object that performs the
33
+
> search.
30
34
31
35
Wikipedia says
32
36
33
-
> In computer programming, the specification pattern is a particular software design pattern, whereby business rules can be recombined by chaining the business rules together using boolean logic.
37
+
> In computer programming, the specification pattern is a particular software design pattern,
38
+
> whereby business rules can be recombined by chaining the business rules together using boolean
39
+
> logic.
34
40
35
41
**Programmatic Example**
36
42
37
-
If we look at our creature pool example from above, we have a set of creatures with certain properties.
38
-
Those properties can be part of a pre-defined, limited set (represented here by the enums Size, Movement and Color); but they can also be continuous values (e.g. the mass of a Creature).
39
-
In this case, it is more appropriate to use what we call "parameterized specification", where the property value can be given as an argument when the Creature is instantiated, allowing for more flexibility.
40
-
A third option is to combine pre-defined and/or parameterized properties using boolean logic, allowing for near-endless selection possibilities (this is called "composite specification", see below).
41
-
The pros and cons of each approach are detailed in the table at the end of this document.
43
+
If we look at our creature pool example from above, we have a set of creatures with certain
44
+
properties. Those properties can be part of a pre-defined, limited set (represented here by the
45
+
enums Size, Movement and Color); but they can also be continuous values (e.g. the mass of a
46
+
Creature). In this case, it is more appropriate to use what we call "parameterized specification",
47
+
where the property value can be given as an argument when the Creature is instantiated, allowing for
48
+
more flexibility. A third option is to combine pre-defined and/or parameterized properties using
49
+
boolean logic, allowing for near-endless selection possibilities (this is called "composite
50
+
specification", see below). The pros and cons of each approach are detailed in the table at the end
51
+
of this document.
42
52
43
53
```java
44
54
publicinterfaceCreature {
@@ -50,7 +60,7 @@ public interface Creature {
50
60
}
51
61
```
52
62
53
-
And ``Dragon`` implementation looks like this.
63
+
And `Dragon` implementation looks like this.
54
64
55
65
```java
56
66
publicclassDragonextendsAbstractCreature {
@@ -61,7 +71,8 @@ public class Dragon extends AbstractCreature {
61
71
}
62
72
```
63
73
64
-
Now that we want to select some subset of them, we use selectors. To select creatures that fly, we should use ``MovementSelector``.
74
+
Now that we want to select some subset of them, we use selectors. To select creatures that fly, we
@@ -111,7 +123,8 @@ But we could also use our parameterized selector like this:
111
123
.collect(Collectors.toList());
112
124
```
113
125
114
-
Our third option is to combine multiple selectors together. Performing a search for special creatures (defined as red, flying, and not small) could be done as follows:
126
+
Our third option is to combine multiple selectors together. Performing a search for special
127
+
creatures (defined as red, flying, and not small) could be done as follows:
115
128
116
129
```java
117
130
var specialCreaturesSelector =
@@ -123,8 +136,9 @@ Our third option is to combine multiple selectors together. Performing a search
123
136
124
137
**More on CompositeSpecification**
125
138
126
-
InCompositeSpecification, we will create custom instances of ``AbstractSelector`` by combining other selectors (called "leaves") using the three basic logical operators.
127
-
These are implemented in ``ConjunctionSelector``, ``DisjunctionSelector`` and ``NegationSelector``.
139
+
InCompositeSpecification, we will create custom instances of `AbstractSelector` by combining
140
+
other selectors (called "leaves") using the three basic logical operators. These are implemented in
141
+
`ConjunctionSelector`, `DisjunctionSelector` and `NegationSelector`.
@@ -163,12 +177,14 @@ public class ConjunctionSelector<T> extends AbstractSelector<T> {
163
177
}
164
178
```
165
179
166
-
All that is left to do is now to create leaf selectors (be it hard-coded or parameterized ones) that are as generic as possible,
167
-
and we will be able to instantiate the ``AbstractSelector`` classby combining any amount of selectors, as exemplified above.
168
-
We should be careful though, as it is easy to make a mistake when combining many logical operators; in particular, we should pay attention to the priority of the operations.\
169
-
In general, Composite Specification is a great way to write more reusable code, as there is no need to create a Selector classfor each filtering operation.
170
-
Instead, we just create an instance of ``AbstractSelector`` "on the spot", using tour generic "leaf" selectors and some basic boolean logic.
171
-
180
+
All that is left to do is now to create leaf selectors (be it hard-coded or parameterized ones) that
181
+
are as generic as possible, and we will be able to instantiate the ``AbstractSelector`` classby
182
+
combining any amount of selectors, as exemplified above. We should be careful though, as it is easy
183
+
to make a mistake when combining many logical operators; in particular, we should pay attention to
184
+
the priority of the operations. In general, Composite Specification is a great way to write more
185
+
reusable code, as there is no need to create a Selector classfor each filtering operation. Instead,
186
+
we just create an instance of ``AbstractSelector`` "on the spot", using tour generic "leaf"
187
+
selectors and some basic boolean logic.
172
188
173
189
**Comparison of the different approaches**
174
190
@@ -181,9 +197,11 @@ Instead, we just create an instance of ``AbstractSelector`` "on the spot", using
181
197
| | | + Supports logical operations | - You still need to create the base classes used as leaves |
0 commit comments