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: fluentinterface/README.md
+74-77Lines changed: 74 additions & 77 deletions
Original file line number
Diff line number
Diff line change
@@ -17,22 +17,13 @@ tag:
17
17
18
18
## Intent
19
19
20
-
A fluent interface provides an easy-readable, flowing interface, that often mimics a domain specific language. Using this pattern results in code that can be read nearly as human language.
20
+
To provide an easily readable, flowing API by chaining method calls.
21
21
22
22
## Explanation
23
23
24
-
The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API. Those
25
-
interfaces tend to mimic domain specific languages, so they can nearly be read as human languages.
26
-
27
-
A fluent interface can be implemented using any of
28
-
29
-
* Method chaining - calling a method returns some object on which further methods can be called.
30
-
* Static factory methods and imports.
31
-
* Named parameters - can be simulated in Java using static factory methods.
24
+
Real-world example
32
25
33
-
Real world example
34
-
35
-
> We need to select numbers based on different criteria from the list. It's a great chance to utilize fluent interface pattern to provide readable easy-to-use developer experience.
26
+
> Imagine you are at a coffee shop and you want to customize your coffee order. Instead of telling the barista everything at once, you specify each customization step-by-step in a way that flows naturally. For instance, you might say, "I'd like a large coffee, add two shots of espresso, no sugar, and top it with almond milk." This approach is similar to the Fluent Interface design pattern, where you chain together method calls to configure an object in a readable and intuitive manner. Just as you specify each part of your coffee order sequentially, a Fluent Interface allows you to chain method calls to build and configure objects step-by-step in code.
36
27
37
28
In plain words
38
29
@@ -44,6 +35,8 @@ Wikipedia says
44
35
45
36
**Programmatic Example**
46
37
38
+
We need to select numbers based on different criteria from the list. It's a great chance to utilize fluent interface pattern to provide readable easy-to-use developer experience.
39
+
47
40
In this example two implementations of a `FluentIterable` interface are given.
48
41
49
42
```java
@@ -87,72 +80,74 @@ public class LazyFluentIterable<E> implements FluentIterable<E> {
87
80
}
88
81
```
89
82
90
-
Their usage is demonstrated with a simple number list that is filtered, transformed and collected. The
91
-
result is printed afterward.
83
+
Their usage is demonstrated with a simple number list that is filtered, transformed and collected. The result is printed afterward.
prettyPrint("The initial list contains: ", integerList);
91
+
92
+
var firstFiveNegatives =SimpleFluentIterable
93
+
.fromCopyOf(integerList)
94
+
.filter(negatives())
95
+
.first(3)
96
+
.asList();
97
+
prettyPrint("The first three negative values are: ", firstFiveNegatives);
98
+
99
+
100
+
var lastTwoPositives =SimpleFluentIterable
101
+
.fromCopyOf(integerList)
102
+
.filter(positives())
103
+
.last(2)
104
+
.asList();
105
+
prettyPrint("The last two positive values are: ", lastTwoPositives);
106
+
107
+
SimpleFluentIterable
108
+
.fromCopyOf(integerList)
109
+
.filter(number -> number %2==0)
110
+
.first()
111
+
.ifPresent(evenNumber ->LOGGER.info("The first even number is: {}", evenNumber));
112
+
113
+
114
+
var transformedList =SimpleFluentIterable
115
+
.fromCopyOf(integerList)
116
+
.filter(negatives())
117
+
.map(transformToString())
118
+
.asList();
119
+
prettyPrint("A string-mapped list of negative numbers contains: ", transformedList);
120
+
121
+
122
+
var lastTwoOfFirstFourStringMapped =LazyFluentIterable
123
+
.from(integerList)
124
+
.filter(positives())
125
+
.first(4)
126
+
.last(2)
127
+
.map(number ->"String["+ number +"]")
128
+
.asList();
129
+
prettyPrint("The lazy list contains the last two of the first four positive numbers "
130
+
+"mapped to Strings: ", lastTwoOfFirstFourStringMapped);
131
+
132
+
LazyFluentIterable
133
+
.from(integerList)
134
+
.filter(negatives())
135
+
.first(2)
136
+
.last()
137
+
.ifPresent(number ->LOGGER.info("Last amongst first two negatives: {}", number));
138
+
}
144
139
```
145
140
146
141
Program output:
147
142
148
-
```java
149
-
The initial list contains:1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2, -68.
150
-
The first three negative values are:-61, -22, -87.
151
-
The last two positive values are:23, 2.
152
-
The first even number is:14
153
-
A string-mapped list of negative numbers contains:String[-61], String[-22], String[-87], String[-82], String[-98], String[-68].
154
-
The lazy list contains the last two of the first four positive numbers mapped to Strings:String[18], String[6].
155
-
Last amongst first two negatives:-22
143
+
```
144
+
08:50:08.260 [main] INFO com.iluwatar.fluentinterface.app.App -- The initial list contains: 1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2, -68.
145
+
08:50:08.265 [main] INFO com.iluwatar.fluentinterface.app.App -- The first three negative values are: -61, -22, -87.
146
+
08:50:08.265 [main] INFO com.iluwatar.fluentinterface.app.App -- The last two positive values are: 23, 2.
147
+
08:50:08.266 [main] INFO com.iluwatar.fluentinterface.app.App -- The first even number is: 14
148
+
08:50:08.267 [main] INFO com.iluwatar.fluentinterface.app.App -- A string-mapped list of negative numbers contains: String[-61], String[-22], String[-87], String[-82], String[-98], String[-68].
149
+
08:50:08.270 [main] INFO com.iluwatar.fluentinterface.app.App -- The lazy list contains the last two of the first four positive numbers mapped to Strings: String[18], String[6].
150
+
08:50:08.270 [main] INFO com.iluwatar.fluentinterface.app.App -- Last amongst first two negatives: -22
156
151
```
157
152
158
153
## Class diagram
@@ -167,6 +162,10 @@ Use the Fluent Interface pattern when
167
162
* Building complex objects step-by-step, and there is a need to make the code more intuitive and less error-prone.
168
163
* Enhancing code clarity and reducing the boilerplate code, especially in configurations and object-building scenarios.
169
164
165
+
## Tutorials
166
+
167
+
*[An Approach to Internal Domain-Specific Languages in Java (InfoQ)](http://www.infoq.com/articles/internal-dsls-java)
*[Domain Specific Languages](https://www.amazon.com/gp/product/0321712943/ref=as_li_tl?ie=UTF8&tag=javadesignpat-20&camp=1789&creative=9325&linkCode=as2&creativeASIN=0321712943&linkId=ad8351d6f5be7d8b7ecdb650731f85df)
199
+
*[Domain-Driven Design: Tackling Complexity in the Heart of Software](https://amzn.to/3UrXkh2)
200
+
*[Domain Specific Languages](https://amzn.to/3R1UYDA)
0 commit comments