Written by Wilco Jansen Friday, 06 November 2009 23:45
With the introduction of chaining methods together in PHP 5 we now have the opportunity to implement Fluent Interfaces in PHP which opens up an interesting way of writing more readable and smaller code.
Fluent Interfaces are not a new programming construct, they provide us with the ability to directly de-reference an object, PHP developers can build objects using fluent interfaces.
On the first look this might look like abracadabra if you are totally new to the new buzzword "Fluent Interfaces". Fluent interfaces are best described as way of chaining methods of an object together. By having a method return a reference to the object itself, return $this; you chain methods together like this:
$this->methodOne()->methodTwo()->methodThree();
The point of using fluent interfaces is simple; to make your code easier to read (and in the end also easier to maintain). My interest has been triggered by the articles Júlio Pontes has been posting on the All Together As A Whole website. A community initiative to gather community developers together. A full list of the articles written by Júlio can be found at the end of this article.
Let's go into some simple examples. We create a semantic database query, to create an Legible API and reusable piece of code. Today usually developers construct "Models" like the following example:
$studentsModel = JModel::getInstance('students');
$studentsModel->getByCity('São Paulo');
$studentsModel->getEnrolleByCurseCity('Computer Science','São Paulo');
In PHP 4 we where "forced" to build applications this way writing an additional lines of code, which we in the end also need to maintain (remember, 80% of the costs come from maintaining code). The proposed solution is to eliminate the necessity to create many methods for every type of criteria. The criteria only configure our Query with will changing on demand and will be executed one time if you need. So on new API the same code will look like this:
$students = new Students;
$students->fromCity('São Paulo')->Enrolled()->inCurse('Computer Science')->inOrder();
Although there are other techniques to refactor the first API, the use of Fluent Interface is a significant advance to the deployment of Domain Specific Language for the users use. Let us discuss the ingredients for constructing this API:
Doing chaining requires a conceptual change. The main point is that the nomenclature of the methods allow the interface to flow naturally. Renaming the methods and returning the object itself can make the call in a friendly way:
class Students{
// previously called setFilterCity
public function fromCity($city) {
echo "Students will be filtered through the city $city";
return $this;
}
// previously called setOrderByName
public function inOrder() {
echo "Students will be sorted by name";
return $this;
}
}
$students = new students();
$students->fromCity('Rio de Janeiro')->inOrder();
Above all it is important to maintain consistency to make it clear what the classes are that work with method chaining, avoiding the wait for the developer to return the object itself wrongly. In these examples the prefix Catalog will be used to identify these classes. The use of name-spaces would be very welcome if the language allowed (and PHP 5.3 does support that, PHP has a bright future :-D).
Example code in Joomla 1.6 would be (be aware we assume the existance of a new ContentDSL class):
$content = new ContentDSL();
$contentRows = $content->lists()->withTitle('My Title')->published()->getRows();
Another example using Fluent Interface:
class car {
private $speed;
private $color;
private $doors;
public function setSpeed($speed){
$this->speed = $speed;
return $this;
}
public function setColor($color) {
$this->color = $color;
return $this;
}
public function setDoors($doors) {
$this->doors = $doors;
return $this;
}
}
// Fluent interface
$myCar = new car();
$myCar->setSpeed(100)->setColor('blue')->setDoors(5);
// Example without fluent interface
$myCar2 = new car();
$myCar2->setSpeed(100);
$myCar2->setColor('blue');
$myCar2->setDoors(5)
Júlio has some more examples about fluent interfaces and how construct complex "gramatics" like:
$rows = $content->lists()->published()->latest()->fromCategory()->withName('Joomla! News")->andContent()->inOrder()->getRows();
Júlio also has been writing about Domain Specific Language (DSL). This is a specific language dedicated to a particular problem/domain, in the example below it refers to content. The idea is create your calls with better names and when you use fluent interface also to make better code, more legible, etc. Let us try to create DSL for 'Content', 'Category' and 'Banner' and make a relation of these for example:
// latest content in order of creation from category with name "latest news"
$content->lists()->latest()->fromCategory()->withName('Latest news')->andContent()->inORder->getRows();
// latest banners in order from category with name "Banners"
$banner->lists()->latest()->fromCategory()->withName('Latest news')->andBanner()->inORder->getRows();
Júlio is working on an installable extension where you can put this into practise, keep an eye on hos work on the All Together As A Whole website. Who knows this might sometimes end up in the core of Joomla...
Are there any practical examples out there where we can see Fluent Interfaces in action? At the end of this blog you will find some material that Júlio Pontes has been writing about on the All Together As A Whole website. Implementations can also be found in the Zend framework, see for example a post on the Zend developer zone desrcibing a basic example on Fluent Interfaces within Zend (actually a very good read!). Within Joomla 1.6 the only practical use of Fluent Interfaces I know of is the new JQuery Class (fare from complete usage), but also on additional frameworks like Nooku there is some brief documentation out there describing an example in Nooku 0.7.
Related articles:
Wilco was born in 1967 in the Netherlands where he still lives. After years of being a programmer Wilco has worked as project manager and IT manager. Discovered Joomla! when he was creating his own content management system, and never lost focus after then. Joined core team as development coordinator in May 2006 just helping to make Joomla! even better then it is already. Wilco has been deeply involved in the Joomla project as Google summer of code program manager 2006, 2007 and 2008 editions, co-organizer of the Google Highly Participation contest in 2008, first ever development coordinator, creator of the Joomla bug squad, member of the board of Open source matters, regular speaker on world wide conference advocating Joomla and much, much more. Wilco has a bachelor degree in business and information engineering and studied Master of Science knowledge and information engineering at the Middlesex University in London.
More about Wilco Jansen
We have a team that works on the blogs presented on this site. Below you will find all present members who are actively working on blogs on this site.
Please contact us if you are interested in helping us out with the creation of the blogs.
jfoobar has readers from all over the world and in many languages. If you create a translation of one of our posts and link to it than please let us know so we can add a link back to the translation at the original post.
Copyright © 2008 jfoobar - All Rights Reserved - Joomla! is a registered trademark of Open Source Matters, Inc - Disclaimer