Cover image for post A sensible place for a fluent interface

A sensible place for a fluent interface

First of all: Happy new year everybody!!

The new buzz term "fluent interface" has been mentioned a lot in the PHP world recently, so I will not again explain, what a "fluent interface" is. Andi already mentioned, that this way of desining an API is quite good and can give you a really handy interface, but he also points out, that one should make very careful use of the technique.

Also I did not know the term "fluent interface" before, we realized, that we already used this in the eZ components, to be more exact, in our Database package, which gives you a quite good ammount of SQL abstraction.

Here is a small example, that creates an SQL query to fetch data from the table "Person":

$q = $db->createSelectQuery(); $q->select( '*' ) ->from( 'Person' ) ->where( $q->expr->gt( 'age', 15 ) ) ->orderBy( 'full_name' ) ->limit( 10 ); $stmt = $q->prepare(); $stmt->execute();

As you can see, after creating a query object, we can manipulate the query it represents through a "fluent interface". After we chose what to select and from which table, we add a WHERE condition which indicates that we search for persons older than 15 years. After that we determine to order the results by the column "full_name". The last call in our "method chain" limits the number of results to 10. Surely in combination with our PersistantObject package (which allows you to store arbitrary data structures into database tables), this is a mighty tool to build very portable applications. And I asume you noticed it's relation to PDO. ;)

Of course, this is only a very small part in the eZ components, where we use a "fluent interface", but I'm absolutly sure, that it makes great sense in this place. The usage is very comfortable and the resulting code is nicely readable. I'm sure, this is a sensible place for a "fluent interface".

P.S.: If you want to see another cool (but not really fluent) interface, take a look at the ezcConsoleTable class. ;)

Comments

I would suggest (and this has probably already been said) that we could make this more abstract by saying that a fluent interface makes sense for methods whose sole purpose is to modify the internal state of the object. This seems obvious to me, but I didn't see that mentioned in my quick skims of recent discussions re: PHP. Certainly fluent interfaces don't always make sense -- and often just result in a confusing API and misleading sourcecode, as others have pointed out. This example makes a lot of sense, though, as does any sort of class where the methods build logical relationships between internal properties, etc.

Hans L at 2006-01-03

So far, my first response to the term 'Fluent interface' was "oh, another buzzword, it'll pass". However, this is one great example of where this technique would be really really useful in improving code readability and clear API setup. I guess it's time to digg deeper into Fluent interfaces.

stefan at 2006-01-04

are you sure?

you just removed $q-> from the beginning of each line...?? - was that such a huge readability problem, (I bet you it's going to be a maintenance nightmare down the road...)

you have ended up with a API for where / from / etc. can never return their previous values, eg.

you cant build and adjust the statement, or change or extend your API in the future.... - It's about as usefull as C#/Java's habit of not requiring "this." before a method call... Unreadable code for the sake of a few characters...

Alan Knowles at 2006-01-05

You code assumes that from() and where() also return the current state also without modifying it when no parameters are given. I think it is much better to add e.g getWhere(), getFrom() etc. if you require this functionality.

As a side note: What is wrong with not requiring this-> in c++ etc? I have worked with this for years and I can't really say that it ever caused any problems for me.

Frederik Holljen at 2006-01-05