Skip to content

Commit 64effdc

Browse files
authored
Create README.md
docs: Translate Fluent Interface into German #2275
1 parent affb8da commit 64effdc

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
---
2+
shortTitle: Fluent Interface
3+
category: Behavioral
4+
language: de
5+
tag:
6+
- API design
7+
- Code simplification
8+
- Decoupling
9+
- Object composition
10+
- Reactive
11+
---
12+
13+
## Alternativbezeichnungen
14+
15+
* Fluent API
16+
* Method Chaining
17+
18+
## Zweck
19+
20+
Primäres Ziel des Fluent-Interface-Pattern ist es, eine gut lesbare sprechende API zur
21+
Verfügung zu stellen, indem Methodenaufrufe einfach verkettet werden können (Method Chaining).
22+
Dieser Ansatz ist ideal, um komplexe Objekte schrittweise zu bauen und generell ein angenehmeres
23+
Programmiererlebnis zu erreichen.
24+
25+
## Detaillierte Erklärung
26+
27+
Vergleichsbeispiel
28+
29+
> Die Bestellung eines frei konfigurierbaren Kaffees in einer Kaffeebar funktioniert ähnlich
30+
> wie das Fluent-Interface-Pattern.
31+
> Dabei teilen Sie dem Barista nicht all ihre Wünsche auf einmal mit, sondern nennen schrittweise
32+
> eine Auswahl nach der anderen, in einem natürlichen Fluss. Sie sagen beispielsweise "Ich möchte
33+
> einen großen großen Kaffee, mit zwei Espresso-Shots, ohne Zucker, plus Mandelmilch".
34+
> Diese Aneinanderhängung von Wünschen entspricht dem Verketten von Methodenaufrufen
35+
> beim Fluent-Interface-Pattern, wodurch der Code zu Objektkonfiguration intuitiv lesbar wird.
36+
> So wie eine Kaffeekomponente nach der anderen ausgewählt wird, wird im Code eine Methode nach der anderen
37+
> ausgeführt.
38+
39+
In einfachen Worten:
40+
41+
> Fluent Interface bietet eine sprechende, leicht lesbare Schnittstelle zum Code.
42+
43+
Wikipedia sagt:
44+
45+
> In der Softwareentwicklung ist Fluent Interface eine objektorientierte API, deren Design auf
46+
> ausgiebiger Verkettung von Methoden beruht. Ziel ist verbesserte Lesbarkeit des Codes
47+
> durch eine domänenspezifische Sprache (DSL, domain specific language).
48+
49+
Ablaufdiagramm
50+
51+
![Fluent Interface sequence diagram](/fluent-interface/etc/fluent-interface-sequence-diagram.png)
52+
53+
## Programmbeispiel
54+
55+
Wir wollen Zahlen aus einer Liste nach verschiedenen Kriterien auswählen. Dabei können
56+
wir die Lesbarkeit des Codes gut mit dem Fluent-Interface-Pattern verbessern.
57+
58+
Der Beispielcode enthält zwei Implementationen eines `FluentIterable`-Interfaces.
59+
60+
```java
61+
public interface FluentIterable<E> extends Iterable<E> {
62+
63+
FluentIterable<E> filter(Predicate<? super E> predicate);
64+
65+
Optional<E> first();
66+
67+
FluentIterable<E> first(int count);
68+
69+
Optional<E> last();
70+
71+
FluentIterable<E> last(int count);
72+
73+
<T> FluentIterable<T> map(Function<? super E, T> function);
74+
75+
List<E> asList();
76+
77+
static <E> List<E> copyToList(Iterable<E> iterable) {
78+
var copy = new ArrayList<E>();
79+
iterable.forEach(copy::add);
80+
return copy;
81+
}
82+
}
83+
```
84+
85+
`SimpleFluentIterable` betreibt gierige Auswertung und wäre für eine reale Anwendung zu rechenintensiv.
86+
87+
```java
88+
public class SimpleFluentIterable<E> implements FluentIterable<E> {
89+
// ...
90+
}
91+
```
92+
`LazyFluentIterable` wertet erst bei Terminierung der Kette aus.
93+
94+
```java
95+
public class LazyFluentIterable<E> implements FluentIterable<E> {
96+
// ...
97+
}
98+
```
99+
100+
Ihre Verwendung zeigen wir mit einer simplen Zahlenliste, die gefiltert, transformiert
101+
und zu einer neuen Liste zusammengestellt wird. Das Ergebnis wird anschließend ausgegeben.
102+
103+
```java
104+
public static void main(String[] args) {
105+
106+
var integerList = List.of(1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2, -68);
107+
108+
prettyPrint("The initial list contains: ", integerList);
109+
110+
var firstThreeNegatives = SimpleFluentIterable
111+
.fromCopyOf(integerList)
112+
.filter(negatives())
113+
.first(3)
114+
.asList();
115+
prettyPrint("The first three negative values are: ", firstThreeNegatives);
116+
117+
118+
var lastTwoPositives = SimpleFluentIterable
119+
.fromCopyOf(integerList)
120+
.filter(positives())
121+
.last(2)
122+
.asList();
123+
prettyPrint("The last two positive values are: ", lastTwoPositives);
124+
125+
SimpleFluentIterable
126+
.fromCopyOf(integerList)
127+
.filter(number -> number % 2 == 0)
128+
.first()
129+
.ifPresent(evenNumber -> LOGGER.info("The first even number is: {}", evenNumber));
130+
131+
132+
var transformedList = SimpleFluentIterable
133+
.fromCopyOf(integerList)
134+
.filter(negatives())
135+
.map(transformToString())
136+
.asList();
137+
prettyPrint("A string-mapped list of negative numbers contains: ", transformedList);
138+
139+
140+
var lastTwoOfFirstFourStringMapped = LazyFluentIterable
141+
.from(integerList)
142+
.filter(positives())
143+
.first(4)
144+
.last(2)
145+
.map(number -> "String[" + number + "]")
146+
.asList();
147+
prettyPrint("The lazy list contains the last two of the first four positive numbers "
148+
+ "mapped to Strings: ", lastTwoOfFirstFourStringMapped);
149+
150+
LazyFluentIterable
151+
.from(integerList)
152+
.filter(negatives())
153+
.first(2)
154+
.last()
155+
.ifPresent(number -> LOGGER.info("Last amongst first two negatives: {}", number));
156+
}
157+
```
158+
159+
Programmausgabe:
160+
161+
```
162+
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.
163+
08:50:08.265 [main] INFO com.iluwatar.fluentinterface.app.App -- The first three negative values are: -61, -22, -87.
164+
08:50:08.265 [main] INFO com.iluwatar.fluentinterface.app.App -- The last two positive values are: 23, 2.
165+
08:50:08.266 [main] INFO com.iluwatar.fluentinterface.app.App -- The first even number is: 14
166+
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].
167+
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].
168+
08:50:08.270 [main] INFO com.iluwatar.fluentinterface.app.App -- Last amongst first two negatives: -22
169+
```
170+
171+
## Verwendung
172+
173+
* Zum Entwurf vielgenutzter APIs, bei denen die Lesbarkeit des sie verwendenden Codes besonders wichtig ist.
174+
* Zur schrittweisen Konstruktion komplexer Objekte mit intuitivem und weniger fehleranfälligem Code.
175+
* Zur Verbesserung der Übersichtlichkeit des Codes und Reduktion von Boilerplate-Code,
176+
speziell bei Konfigurationen und Objektkonstruktion.
177+
178+
## Tutorials
179+
180+
* [An Approach to Internal Domain-Specific Languages in Java (InfoQ)](http://www.infoq.com/articles/internal-dsls-java)
181+
182+
## Reale Anwendungen in Java
183+
184+
* [Java 8 Stream API](http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html)
185+
* [Google Guava FluentIterable](https://github.com/google/guava/wiki/FunctionalExplained)
186+
* [JOOQ](http://www.jooq.org/doc/3.0/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder/)
187+
* [Mockito](http://mockito.org/)
188+
* [Java Hamcrest](http://code.google.com/p/hamcrest/wiki/Tutorial)
189+
* Builder in Bibliotheken wie Apache Camel für den Integrations-Workflow.
190+
191+
## Vor- und Nachteile
192+
193+
Vorteile:
194+
195+
* Signifikant erhöhte Lesbarkeit und Wartbarkeit des Codes
196+
* Unterstützt die Konstruktion unveränderlicher Objekte, weil die Methoden typischerweise neue Instanzen zurückgeben.
197+
* Weniger Variablen nötig, da der Kontext durch die Aufrufkette klar wird.
198+
199+
Nachteile:
200+
201+
* Für Neulinge ist der Code weniger intuitiv.
202+
* Verkettung von Methoden erschwert das Debuggen.
203+
* Übermäßige Verwendung kann zu komplexem schwer wartbarem Code führen.
204+
205+
## Verwandte Patterns
206+
207+
* [Builder](https://java-design-patterns.com/patterns/builder/): Verwendet oft Fluent Interface zur schrittweisen Konstruktion. Bei Builder geht es um die Konstruktion komplexer Objekte, bei Fluent Interface um die Methodenverkettung.
208+
* [Chain of Responsibility](https://java-design-patterns.com/patterns/chain-of-responsibility/): Fluent Interfaces können als spezielle Verwendung von Chain of Responsibility betrachtet werden, wo jede Methode in der Kette eine Teilaufgabe behandelt und ihr Ergebnis an die nächste Methode weiterreicht.
209+
210+
## Quellen
211+
212+
* [Domain-Driven Design: Tackling Complexity in the Heart of Software](https://amzn.to/3UrXkh2)
213+
* [Domain Specific Languages](https://amzn.to/3R1UYDA)
214+
* [Effective Java](https://amzn.to/4d4azvL)
215+
* [Java Design Pattern Essentials](https://amzn.to/44bs6hG)
216+
* [Fluent Interface (Martin Fowler)](http://www.martinfowler.com/bliki/FluentInterface.html)

0 commit comments

Comments
 (0)