Wednesday, May 13, 2009

Become fluent with fluent interfaces

It's been a while since I first read about fluent interfaces, and of course it's been a while I've been using them too, like every test infected guy.

Yesterday I finally decided to give them a try and implement one for a Builder: implementing a fluent interface is embarassingly easy, as basically all you have to do is create setters that return the builder itself and a method that returns the object you're creating.

To give the simplest example that comes to my mind, if you wanted to create an order you could write someting like
OrderBuilder.createOrder()
.forCustomer(customer)
.with(STEAK, 1)
.with(FRIES, 1)
.with(BEER, 3)
.build();
The builder actual code might look something like this:
public class OrderBuilder {

private final Order order;

private OrderBuilder() {
this.order = new Order();
}

public static OrderBuilder createOrder() {
return new OrderBuilder();
}

public OrderBuilder forCustomer(Customer customer) {
order.setCustomer(customer);
return this;
}

// ...similar setters ...

public Order build() {
// ...maybe perform some validation
return order;
}
}
After playing with my code for a while I discovered that implementing a good fluent interface is not as easy as it might seem at first: you have to carefully think about what you really want to do (program by intention), how to clearly express it, and have your APIs reflect it. Nevertheless I think I'll experiment with them a little, they could be another nice trick in my toolbox.

No comments: