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
* Resolution proposition to Issue#1055 (UML diagram left to do)
* Deciding not to modify the UML diagram for now
* Resolution proposition to Issue#1093
* Code reformatting
Copy file name to clipboardExpand all lines: specification/README.md
+81-17Lines changed: 81 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -31,7 +31,8 @@ Use the Specification pattern when
31
31
32
32
Real world example
33
33
34
-
> There is a pool of different creatures and we often need to select some subset of them. We can write our search specification such as "creatures that can fly" or "creatures heavier than 500 kilograms" and give it to the party that will perform the filtering.
34
+
> There is a pool of different creatures and we often need to select some subset of them.
35
+
> 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.
35
36
36
37
In Plain Words
37
38
@@ -44,8 +45,10 @@ Wikipedia says
44
45
**Programmatic Example**
45
46
46
47
If we look at our creature pool example from above, we have a set of creatures with certain properties.\
47
-
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 discrete (e.g. the mass of a Creature). 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 created, allowing for more flexibility.
48
-
48
+
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).
49
+
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.
50
+
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).
51
+
The pros and cons of each approach are detailed in the table at the end of this document.
49
52
```java
50
53
publicinterfaceCreature {
51
54
StringgetName();
@@ -56,8 +59,7 @@ public interface Creature {
56
59
}
57
60
```
58
61
59
-
And dragon implementation looks like this.
60
-
62
+
And ``Dragon`` implementation looks like this.
61
63
```java
62
64
publicclassDragonextendsAbstractCreature {
63
65
@@ -67,10 +69,9 @@ public class Dragon extends AbstractCreature {
67
69
}
68
70
```
69
71
70
-
Now that we want to select some subset of them, we use selectors. To select creatures that fly, we should use MovementSelector.
71
-
72
+
Now that we want to select some subset of them, we use selectors. To select creatures that fly, we should use ``MovementSelector``.
But we could also use our paramterized selector like this.
118
+
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 :
InCompositeSpecification, we will create custom instances of ``AbstractSelector`` by combining other selectors (called "leaves") using the three basic logical operators.
130
+
These are implemented in ``ConjunctionSelector``, ``DisjunctionSelector`` and ``NegationSelector``.
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,
168
+
and we will be able to instantiate the ``AbstractSelector`` classby combining any amount of selectors, as exemplified above.
169
+
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.\
170
+
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.
171
+
Instead, we just create an instance of ``AbstractSelector`` "on the spot", using tour generic "leaf" selectors and some basic boolean logic.
172
+
173
+
174
+
**Comparison of the different approaches**
175
+
176
+
| Pattern | Usage | Pros | Cons |
177
+
|---|---|---|---|
178
+
| Hard-Coded Specification | Selection criteria are few and known in advance | + Easy to implement | - Inflexible |
179
+
| | | + Expressive |
180
+
| Parameterized Specification | Selection criteria are a large range of values (e.g. mass, speed,...) | + Some flexibility | - Still requires special-purpose classes |
181
+
| Composite Specification | There are a lot of selection criteria that can be combined in multiple ways, hence it is not feasible to create a classfor each selector | + Very flexible, without requiring many specialized classes | - Somewhat more difficult to comprehend |
182
+
| | | + Supports logical operations | - You still need to create the base classes used as leaves |
0 commit comments