2015-09-07 13:25:26 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								layout: pattern
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								title: Fluent Interface
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								folder: fluentinterface
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								permalink: /patterns/fluentinterface/
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 21:09:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								categories: Functional
							 
						 
					
						
							
								
									
										
										
										
											2015-09-11 13:08:50 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								tags: 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 21:09:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 -  Reactive
							 
						 
					
						
							
								
									
										
										
										
											2015-09-07 13:25:26 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-03 21:14:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								## Intent
  
						 
					
						
							
								
									
										
										
										
											2020-07-23 18:27:00 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								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.
							 
						 
					
						
							
								
									
										
										
										
											2015-09-07 13:25:26 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-23 18:27:00 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								## Explanation
  
						 
					
						
							
								
									
										
										
										
											2015-09-11 13:08:50 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-23 18:27:00 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								The Fluent Interface pattern is useful when you want to provide an easy readable, flowing API. Those interfaces tend 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								to mimic domain specific languages, so they can nearly be read as human languages.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-11 13:08:50 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								A fluent interface can be implemented using any of
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Method Chaining - calling a method returns some object on which further methods can be called.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Static Factory Methods and Imports
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Named parameters - can be simulated in Java using static factory methods.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-23 18:27:00 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Real world example
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								>  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. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								In plain words
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								>  Fluent Interface pattern provides easily readable flowing interface to code.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Wikipedia says
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								>  In software engineering, a fluent interface is an object-oriented API whose design relies extensively on method chaining. Its goal is to increase code legibility by creating a domain-specific language (DSL).
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								**Programmatic Example**
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								In this example two implementations of a `FluentIterable`  interface are given.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public interface FluentIterable< E >  extends Iterable< E >  {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FluentIterable< E >  filter(Predicate< ? super E> predicate);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Optional< E >  first();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FluentIterable< E >  first(int count);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Optional< E >  last();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FluentIterable< E >  last(int count);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  < T >  FluentIterable< T >  map(Function< ? super E, T> function);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  List< E >  asList();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  static < E >  List< E >  copyToList(Iterable< E >  iterable) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var copy = new ArrayList< E > ();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    iterable.forEach(copy::add);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return copy;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The `SimpleFluentIterable`  evaluates eagerly and would be too costly for real world applications.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public class SimpleFluentIterable< E >  implements FluentIterable< E >  {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								The `LazyFluentIterable`  is evaluated on termination.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public class LazyFluentIterable< E >  implements FluentIterable< E >  {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Their usage is demonstrated with a simple number list that is filtered, transformed and collected. The 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								result is printed afterwards.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```java
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var integerList = List.of(1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2, -68);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prettyPrint("The initial list contains: ", integerList);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var firstFiveNegatives = SimpleFluentIterable
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .fromCopyOf(integerList)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .filter(negatives())
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .first(3)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .asList();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prettyPrint("The first three negative values are: ", firstFiveNegatives);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var lastTwoPositives = SimpleFluentIterable
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .fromCopyOf(integerList)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .filter(positives())
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .last(2)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .asList();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prettyPrint("The last two positive values are: ", lastTwoPositives);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SimpleFluentIterable
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .fromCopyOf(integerList)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .filter(number -> number % 2 == 0)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .first()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .ifPresent(evenNumber -> LOGGER.info("The first even number is: {}", evenNumber));
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var transformedList = SimpleFluentIterable
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .fromCopyOf(integerList)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .filter(negatives())
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .map(transformToString())
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .asList();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prettyPrint("A string-mapped list of negative numbers contains: ", transformedList);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var lastTwoOfFirstFourStringMapped = LazyFluentIterable
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .from(integerList)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .filter(positives())
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .first(4)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .last(2)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .map(number -> "String[" + valueOf(number) + "]")
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .asList();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prettyPrint("The lazy list contains the last two of the first four positive numbers "
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        + "mapped to Strings: ", lastTwoOfFirstFourStringMapped);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    LazyFluentIterable
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .from(integerList)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .filter(negatives())
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .first(2)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .last()
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        .ifPresent(number -> LOGGER.info("Last amongst first two negatives: {}", number));
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The initial list contains: 1, -61, 14, -22, 18, -87, 6, 64, -82, 26, -98, 97, 45, 23, 2, -68.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The first three negative values are: -61, -22, -87.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The last two positive values are: 23, 2.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The first even number is: 14
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // A string-mapped list of negative numbers contains: String[-61], String[-22], String[-87], String[-82], String[-98], String[-68].
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // The lazy list contains the last two of the first four positive numbers mapped to Strings: String[18], String[6].
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Last amongst first two negatives: -22    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-07 20:01:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								## Class diagram
  
						 
					
						
							
								
									
										
										
										
											2015-09-07 13:25:26 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-03 21:14:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								## Applicability
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Use the Fluent Interface pattern when
							 
						 
					
						
							
								
									
										
										
										
											2015-09-07 13:25:26 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-23 18:27:00 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*  You provide an API that would benefit from a DSL-like usage 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  You have objects that are difficult to configure or use 
						 
					
						
							
								
									
										
										
										
											2015-09-07 13:25:26 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-23 18:27:00 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								## Known uses
  
						 
					
						
							
								
									
										
										
										
											2015-09-07 13:25:26 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  [Java 8 Stream API ](http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  [Google Guava FluentInterable ](https://github.com/google/guava/wiki/FunctionalExplained ) 
						 
					
						
							
								
									
										
										
										
											2015-09-11 13:08:50 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*  [JOOQ ](http://www.jooq.org/doc/3.0/manual/getting-started/use-cases/jooq-as-a-standalone-sql-builder/ ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  [Mockito ](http://mockito.org/ ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  [Java Hamcrest ](http://code.google.com/p/hamcrest/wiki/Tutorial ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-03 21:14:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								## Credits
  
						 
					
						
							
								
									
										
										
										
											2015-09-11 13:08:50 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  [Fluent Interface - Martin Fowler ](http://www.martinfowler.com/bliki/FluentInterface.html ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  [Evolutionary architecture and emergent design: Fluent interfaces - Neal Ford ](http://www.ibm.com/developerworks/library/j-eaed14/ ) 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*  [Internal DSL ](http://www.infoq.com/articles/internal-dsls-java ) 
						 
					
						
							
								
									
										
										
										
											2020-07-23 18:27:00 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*  [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 )