schlitt.info - php, photography and private stuff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :Author: Tobias Schlitt :Date: Wed, 19 Nov 2008 23:29:46 +0100 :Revision: 1 :Copyright: CC by-nc-sa ======================================= A sensible place for a fluent interface ======================================= :Description: First of all: **Happy new year everybody!!** 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. .. __: http://www.mikenaberezny.com/archives/35 .. __: http://andigutmans.blogspot.com/2005/12/fluent-interfaces.html 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. .. __: http://ez.no/products/ez_components .. __: http://ez.no/doc/components/view/(file)/1.0beta2/classtrees_Database.html 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. ;) .. __: http://ez.no/doc/components/view/(file)/1.0beta2/classtrees_PersistentObject.html 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". .. __: http://ez.no/products/ez_components P.S.: If you want to see another cool (but not really fluent) interface, take a look at the `ezcConsoleTable`__ class. ;) .. __: http://ez.no/doc/components/view/(file)/1.0beta2/ConsoleTools/ezcConsoleTable.html .. Local Variables: mode: rst fill-column: 79 End: vim: et syn=rst tw=79 Trackbacks ========== - Latest News on Tue, 05 Feb 2008 12:23:38 +0100 in Latest News Latest News Comments ======== - Hans L at Tue, 03 Jan 2006 18:38:44 +0100 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. - stefan at Wed, 04 Jan 2006 10:44:09 +0100 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. - Alan Knowles at Thu, 05 Jan 2006 01:14:52 +0100 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. if ($x->from() == "Person") { $oldwhere = $x->where(); $x->where("(abc NOT NULL) AND ($oldwhere))") } 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... - Frederik Holljen at Thu, 05 Jan 2006 09:23:10 +0100 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.