Fluent Interface is part of domain-specific language DSL, the basic idea of the fluent interfaces is to rationalise a sequence of sequences. Using FI is quite simple to understand and also very readable.
There are some benefits of using fluent interfaces, first of all is the quality of the code, or at least how easy to read and understand it turns.
Testability
The second point is about testability. Implementing fluent interfaces you have to have methods returning something different than void, so it forces you to return at least the object, so for unitary test it’s perfect, because you know the parameters and also know what to wait as response, instead of verify the result of the method looking in other objects.
Proxies and Constructors
Other good point in this discussion is to create proxy for inside objects. For instance, supposing we have two classes: Person and Address, and each Person has one Address.
The basic, without using fluent interface way to write a code that sets and Address into Person could looks like this:
Person person = new Person();
person.setId(1);
person.setName("Name");
Address address = new Address();
address.setId(1);
address.setName("Your street name");
person.setAddress(address);
Now, let’s think a little bit about the reasons. Looking at this example there is any reason to have at Person class a default constructor? I mean, can exist a Person without an Id and a Name? Maybe a Person without Address could be acceptable, but not without and Id and Name, so why don’t put this obligatory fields into constructor?
Second point, for the same reason of the Person, can you imagine and Address without the street’s name? Neither me. Let’s change this code to looks more simple and friendly.
Person person = new Person(1, "Name");
person.setAddress(1, "Street Name")
.setMotherName("Mom")
.setFatherName("Dad")
.setAge(30);
The main attributes are included as parameter into the constructor and the others attributes can be included outside the constructor, for instance, father’s name, mother’s name, age.
All the magic happens just applying the fluent interface. The code for the first peace of code is very basic, just two Java Beans full of gets and sets methods, on the other hand the JavaBeans’s code for the second example is a bit more sophisticated, looking like this:
Address:
public class Address {
private Integer id;
private String street;
public Address(Integer id, String street) {
this.id = id;
this.street = street;
}
public Integer getId() {
return id;
}
public Address setId(Integer id) {
this.id = id;
return this;
}
public String getStreet() {
return street;
}
public Address setStreet(String street) {
this.street = street;
return this;
}
}
Person:
public class Person {
private Integer id;
private String name, motherName, fatherName, age;
private Address address;
public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
public Person setAddress(Integer id, String streetName) {
address = new Address(id, streetName);
return this;
}
public String getMotherName() {
return motherName;
}
public Person setMotherName(String motherName) {
this.motherName = motherName;
return this;
}
public String getFatherName() {
return fatherName;
}
public Person setFatherName(String fatherName) {
this.fatherName = fatherName;
return this;
}
public String getAge() {
return age;
}
public Person setAge(String age) {
this.age = age;
return this;
}
}
Maintenance
If you’re not convinced about simplicity, think about maintenance. If something changes during the development process, let’s say that the Product Owner have changed idea about the product, and the name of the street in the Address is not quite significant to have just “Name”, he prefers to have something like: “Street Name”.
Not using fluent interface you, as developer, you should update all classes that have used the Address class, at this example we have two business classes that use Address via Person object.
Having using some good development tools like Eclipse, Netbeans or JEdit this task will not take too long to be re factored, but I’m not sure about unit tests. Some cumbersome work have to be done to all unitary test starts to work again.
But using fluent interfaces, instead of changing all your business classes - at this example luckily just 2 classes - you can change just the Person class, once that this is the entity that knows exactly how to manipulate the values to fill out the Address object.
Conclusion
Using fluent interfaces, improve your code not just letting it more readable, but also less cumbersome with something has to be changed in the middle of the development process.