Skip to content

Commit a4854d9

Browse files
committed
Merge branch 'master' into add-checkstyle-into-maven
# Conflicts: # pom.xml
2 parents 31537a2 + 3ebc64c commit a4854d9

File tree

16 files changed

+954
-8
lines changed

16 files changed

+954
-8
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@ language: java
33
jdk:
44
- oraclejdk8
55

6+
env:
7+
global:
8+
- GH_REF: github.com/iluwatar/java-design-patterns.git
9+
- secure: "LxTDuNS/rBWIvKkaEqr79ImZAe48mCdoYCF41coxNXgNoippo4GIBArknqtv+XvdkiuRZ1yGyj6pn8GU33c/yn+krddTUkVCwTbVatbalW5jhQjDbHYym/JcxaK9ZS/3JTeGcWrBgiPqHEEDhCf26vPZsXoMSeVCEORVKTp1BSg="
10+
611
before_install:
712
- "export DISPLAY=:99.0"
813
- "sh -e /etc/init.d/xvfb start"
914

1015
after_success:
1116
- mvn clean test jacoco:report coveralls:report
17+
- bash update-ghpages.sh
1218

1319
# Migration to container-based infrastructure
1420
sudo: false

factory-method/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ title: Factory Method
44
folder: factory-method
55
permalink: /patterns/factory-method/
66
categories: Creational
7-
tags: Java
7+
tags:
8+
- Java
9+
- Difficulty-Beginner
810
---
911

1012
**Intent:** Define an interface for creating an object, but let subclasses

faq.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,7 @@ As for performance and scalability, pools can become bottlenecks, if all the
6161
pooled objects are in use and more clients need them, threads will become
6262
blocked waiting for available object from the pool. This is not the case with
6363
Flyweight.
64+
65+
### Q7: What are the differences between FluentInterface and Builder patterns? {#Q7}
66+
67+
Fluent interfaces are sometimes confused with the Builder pattern, because they share method chaining and a fluent usage. However, fluent interfaces are not primarily used to create shared (mutable) objects, but to configure complex objects without having to respecify the target object on every property change.
81.5 KB
Loading
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<class-diagram version="1.1.8" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
3+
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
4+
<class id="1" language="java" name="com.iluwatar.fluentinterface.App" project="fluentinterface"
5+
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/App.java" binary="false" corner="BOTTOM_RIGHT">
6+
<position height="-1" width="-1" x="289" y="-8"/>
7+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
8+
sort-features="false" accessors="true" visibility="true">
9+
<attributes public="true" package="false" protected="false" private="false" static="false"/>
10+
<operations public="true" package="true" protected="true" private="false" static="true"/>
11+
</display>
12+
</class>
13+
<class id="2" language="java" name="com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable"
14+
project="fluentinterface"
15+
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterable.java"
16+
binary="false" corner="BOTTOM_RIGHT">
17+
<position height="-1" width="-1" x="450" y="430"/>
18+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
19+
sort-features="false" accessors="true" visibility="true">
20+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
21+
<operations public="true" package="true" protected="true" private="true" static="true"/>
22+
</display>
23+
</class>
24+
<class id="3" language="java" name="com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable"
25+
project="fluentinterface"
26+
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java"
27+
binary="false" corner="BOTTOM_RIGHT">
28+
<position height="-1" width="-1" x="860" y="391"/>
29+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
30+
sort-features="false" accessors="true" visibility="true">
31+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
32+
<operations public="true" package="true" protected="true" private="true" static="true"/>
33+
</display>
34+
</class>
35+
<interface id="4" language="java" name="com.iluwatar.fluentinterface.fluentiterable.FluentIterable"
36+
project="fluentinterface"
37+
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterable.java" binary="false"
38+
corner="BOTTOM_RIGHT">
39+
<position height="-1" width="-1" x="794" y="55"/>
40+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
41+
sort-features="false" accessors="true" visibility="true">
42+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
43+
<operations public="true" package="true" protected="true" private="true" static="true"/>
44+
</display>
45+
</interface>
46+
<class id="5" language="java" name="com.iluwatar.fluentinterface.fluentiterable.lazy.DecoratingIterator"
47+
project="fluentinterface"
48+
file="/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/DecoratingIterator.java"
49+
binary="false" corner="BOTTOM_RIGHT">
50+
<position height="-1" width="-1" x="1245" y="391"/>
51+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
52+
sort-features="false" accessors="true" visibility="true">
53+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
54+
<operations public="true" package="true" protected="true" private="true" static="true"/>
55+
</display>
56+
</class>
57+
<interface id="6" language="java" name="java.lang.Iterable" project="fluentinterface"
58+
file="/opt/Softwares/Eclipses/MARS/eclipse/jre/lib/rt.jar" binary="true" corner="BOTTOM_RIGHT">
59+
<position height="-1" width="-1" x="793" y="-163"/>
60+
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
61+
sort-features="false" accessors="true" visibility="true">
62+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
63+
<operations public="true" package="true" protected="true" private="true" static="true"/>
64+
</display>
65+
</interface>
66+
<dependency id="7">
67+
<end type="SOURCE" refId="1"/>
68+
<end type="TARGET" refId="2"/>
69+
</dependency>
70+
<realization id="8">
71+
<end type="SOURCE" refId="3"/>
72+
<end type="TARGET" refId="4"/>
73+
</realization>
74+
<dependency id="9">
75+
<end type="SOURCE" refId="3"/>
76+
<end type="TARGET" refId="5"/>
77+
</dependency>
78+
<generalization id="10">
79+
<end type="SOURCE" refId="4"/>
80+
<end type="TARGET" refId="6"/>
81+
</generalization>
82+
<dependency id="11">
83+
<end type="SOURCE" refId="1"/>
84+
<end type="TARGET" refId="3"/>
85+
</dependency>
86+
<dependency id="12">
87+
<end type="SOURCE" refId="1"/>
88+
<end type="TARGET" refId="4"/>
89+
</dependency>
90+
<realization id="13">
91+
<end type="SOURCE" refId="2"/>
92+
<end type="TARGET" refId="4"/>
93+
</realization>
94+
<classifier-display autosize="true" stereotype="true" package="true" initial-value="true" signature="true"
95+
sort-features="false" accessors="true" visibility="true">
96+
<attributes public="true" package="true" protected="true" private="true" static="true"/>
97+
<operations public="true" package="true" protected="true" private="true" static="true"/>
98+
</classifier-display>
99+
<association-display labels="true" multiplicity="true"/>
100+
</class-diagram>

fluentinterface/index.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
layout: pattern
3+
title: Fluent Interface
4+
folder: fluentinterface
5+
permalink: /patterns/fluentinterface/
6+
categories: Other
7+
tags:
8+
- Java
9+
- Difficulty-Intermediate
10+
---
11+
12+
**Intent:** 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.
13+
14+
**Implementation:**
15+
16+
A fluent interface can be implemented using any of
17+
18+
* Method Chaining - calling a method returns some object on which further methods can be called.
19+
* Static Factory Methods and Imports
20+
* Named parameters - can be simulated in Java using static factory methods.
21+
22+
![Fluent Interface](./etc/fluentinterface.png "Fluent Interface")
23+
24+
25+
**Applicability:** Use the Fluent Interface pattern when
26+
27+
* you provide an API that would benefit from a DSL-like usage
28+
* you have objects that are difficult to configure or use
29+
30+
**Real world examples:**
31+
32+
* [Java 8 Stream API](http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html)
33+
* [Google Guava FluentInterable](https://github.com/google/guava/wiki/FunctionalExplained)
34+
* [JOOQ](http://www.jooq.org/doc/3.0/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder/)
35+
* [Mockito](http://mockito.org/)
36+
* [Java Hamcrest](http://code.google.com/p/hamcrest/wiki/Tutorial)
37+
38+
**Credits**
39+
40+
* [Fluent Interface - Martin Fowler](http://www.martinfowler.com/bliki/FluentInterface.html)
41+
* [Evolutionary architecture and emergent design: Fluent interfaces - Neal Ford](http://www.ibm.com/developerworks/library/j-eaed14/)
42+
* [Internal DSL](http://www.infoq.com/articles/internal-dsls-java)

fluentinterface/pom.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>java-design-patterns</artifactId>
7+
<groupId>com.iluwatar</groupId>
8+
<version>1.6.0</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>fluentinterface</artifactId>
13+
<dependencies>
14+
<dependency>
15+
<groupId>junit</groupId>
16+
<artifactId>junit</artifactId>
17+
<scope>test</scope>
18+
</dependency>
19+
</dependencies>
20+
</project>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.iluwatar.fluentinterface;
2+
3+
import com.iluwatar.fluentinterface.fluentiterable.FluentIterable;
4+
import com.iluwatar.fluentinterface.fluentiterable.lazy.LazyFluentIterable;
5+
import com.iluwatar.fluentinterface.fluentiterable.simple.SimpleFluentIterable;
6+
7+
import java.util.*;
8+
import java.util.function.Function;
9+
import java.util.function.Predicate;
10+
11+
import static java.lang.String.valueOf;
12+
13+
/**
14+
* Fluent interface pattern is useful when you want to provide an easy readable, flowing API. Those
15+
* interfaces tend to mimic domain specific languages, so they can nearly be read as human
16+
* languages.
17+
* <p>
18+
* In this example two implementations of a {@link FluentIterable} interface are given. The
19+
* SimpleFluentIterable evaluates eagerly and would be too costly for real world applications. The
20+
* LazyFluentIterable is evaluated on termination. Their usage is demonstrated with a simple number
21+
* list that is filtered, transformed and collected. The result is printed afterwards.
22+
* <p>
23+
*/
24+
public class App {
25+
26+
public static void main(String[] args) {
27+
28+
List<Integer> integerList = new ArrayList<>();
29+
integerList.addAll(Arrays.asList(
30+
1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97,
31+
45, 23, 2, -68, 45
32+
));
33+
34+
prettyPrint("The initial list contains: ", integerList);
35+
36+
List<Integer> firstFiveNegatives =
37+
SimpleFluentIterable.fromCopyOf(integerList).filter(negatives()).first(3).asList();
38+
prettyPrint("The first three negative values are: ", firstFiveNegatives);
39+
40+
41+
List<Integer> lastTwoPositives =
42+
SimpleFluentIterable.fromCopyOf(integerList).filter(positives()).last(2).asList();
43+
prettyPrint("The last two positive values are: ", lastTwoPositives);
44+
45+
SimpleFluentIterable
46+
.fromCopyOf(integerList)
47+
.filter(number -> number % 2 == 0)
48+
.first()
49+
.ifPresent(
50+
evenNumber -> System.out.println(String.format("The first even number is: %d",
51+
evenNumber)));
52+
53+
54+
List<String> transformedList =
55+
SimpleFluentIterable.fromCopyOf(integerList).filter(negatives()).map(transformToString())
56+
.asList();
57+
prettyPrint("A string-mapped list of negative numbers contains: ", transformedList);
58+
59+
60+
List<String> lastTwoOfFirstFourStringMapped =
61+
LazyFluentIterable.from(integerList).filter(positives()).first(4).last(2)
62+
.map(number -> "String[" + String.valueOf(number) + "]").asList();
63+
prettyPrint(
64+
"The lazy list contains the last two of the first four positive numbers mapped to Strings: ",
65+
lastTwoOfFirstFourStringMapped);
66+
67+
LazyFluentIterable
68+
.from(integerList)
69+
.filter(negatives())
70+
.first(2)
71+
.last()
72+
.ifPresent(
73+
lastOfFirstTwo -> System.out.println(String.format(
74+
"The last of the first two negatives is: %d", lastOfFirstTwo)));
75+
}
76+
77+
private static Function<Integer, String> transformToString() {
78+
return integer -> "String[" + valueOf(integer) + "]";
79+
}
80+
81+
private static Predicate<? super Integer> negatives() {
82+
return integer -> (integer < 0);
83+
}
84+
85+
private static Predicate<? super Integer> positives() {
86+
return integer -> (integer > 0);
87+
}
88+
89+
private static <TYPE> void prettyPrint(String prefix, Iterable<TYPE> iterable) {
90+
prettyPrint(", ", prefix, ".", iterable);
91+
}
92+
93+
private static <TYPE> void prettyPrint(String delimiter, String prefix, String suffix,
94+
Iterable<TYPE> iterable) {
95+
StringJoiner joiner = new StringJoiner(delimiter, prefix, ".");
96+
Iterator<TYPE> iterator = iterable.iterator();
97+
while (iterator.hasNext()) {
98+
joiner.add(iterator.next().toString());
99+
}
100+
101+
System.out.println(joiner);
102+
}
103+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package com.iluwatar.fluentinterface.fluentiterable;
2+
3+
import java.util.ArrayList;
4+
import java.util.Iterator;
5+
import java.util.List;
6+
import java.util.Optional;
7+
import java.util.function.Function;
8+
import java.util.function.Predicate;
9+
10+
/**
11+
* The FluentIterable is a more convenient implementation of the common iterable interface based on
12+
* the fluent interface design pattern. This interface defines common operations, but doesn't aim to
13+
* be complete. It was inspired by Guava's com.google.common.collect.FluentIterable.
14+
*
15+
* @param <TYPE> is the class of objects the iterable contains
16+
*/
17+
public interface FluentIterable<TYPE> extends Iterable<TYPE> {
18+
19+
/**
20+
* Filters the contents of Iterable using the given predicate, leaving only the ones which satisfy
21+
* the predicate.
22+
*
23+
* @param predicate the condition to test with for the filtering. If the test is negative, the
24+
* tested object is removed by the iterator.
25+
* @return a filtered FluentIterable
26+
*/
27+
FluentIterable<TYPE> filter(Predicate<? super TYPE> predicate);
28+
29+
/**
30+
* Returns an Optional containing the first element of this iterable if present, else returns
31+
* Optional.empty().
32+
*
33+
* @return the first element after the iteration is evaluated
34+
*/
35+
Optional<TYPE> first();
36+
37+
/**
38+
* Evaluates the iteration and leaves only the count first elements.
39+
*
40+
* @return the first count elements as an Iterable
41+
*/
42+
FluentIterable<TYPE> first(int count);
43+
44+
/**
45+
* Evaluates the iteration and returns the last element. This is a terminating operation.
46+
*
47+
* @return the last element after the iteration is evaluated
48+
*/
49+
Optional<TYPE> last();
50+
51+
/**
52+
* Evaluates the iteration and leaves only the count last elements.
53+
*
54+
* @return the last counts elements as an Iterable
55+
*/
56+
FluentIterable<TYPE> last(int count);
57+
58+
/**
59+
* Transforms this FluentIterable into a new one containing objects of the type NEW_TYPE.
60+
*
61+
* @param function a function that transforms an instance of TYPE into an instance of NEW_TYPE
62+
* @param <NEW_TYPE> the target type of the transformation
63+
* @return a new FluentIterable of the new type
64+
*/
65+
<NEW_TYPE> FluentIterable<NEW_TYPE> map(Function<? super TYPE, NEW_TYPE> function);
66+
67+
/**
68+
* Returns the contents of this Iterable as a List.
69+
*
70+
* @return a List representation of this Iterable
71+
*/
72+
List<TYPE> asList();
73+
74+
/**
75+
* Utility method that iterates over iterable and adds the contents to a list.
76+
*
77+
* @param iterable the iterable to collect
78+
* @param <TYPE> the type of the objects to iterate
79+
* @return a list with all objects of the given iterator
80+
*/
81+
static <TYPE> List<TYPE> copyToList(Iterable<TYPE> iterable) {
82+
ArrayList<TYPE> copy = new ArrayList<>();
83+
Iterator<TYPE> iterator = iterable.iterator();
84+
while (iterator.hasNext()) {
85+
copy.add(iterator.next());
86+
}
87+
return copy;
88+
}
89+
}

0 commit comments

Comments
 (0)