Making Code More Readable Using The Fluent Interface

Loading

From the Wikipedia
"In software engineering, a fluent interface (as first coined by Eric Evans and Martin Fowler) is a way of implementing an object oriented API in a way that aims to provide for more readable code."

Let us explore the fluent interface with the help of an example.

<?php
class Customer
{
    protected 
$_name;
    protected 
$_street;
    protected 
$_city;
    protected 
$_country;

    public function 
setName($name)
    {
        
$this->_name $name;
    }

    public function 
setStreetAddress($street)
    {
        
$this->_street $street;
    }

    public function 
setCity($city)
    {
        
$this->_city $city;
    }

    public function 
setCountry($country)
    {
        
$this->_country $country;
    }

    public function 
save()
    {
        echo 
"Customer information saved";
   
    }
}
?>

We have a Customer class. We set various customer attributes using setter methods and finally save it. Consider the following usage of the Customer class.

<?php
$customer 
= new Customer;

$customer->setName('James Bond');

$customer->setStreetAddress('Abc street');

$customer->setCity('London');

$customer->setCountry('England');

$customer->save();
?>

The code speaks for itself. We create the Customer object and set name, address, city, country and finally call the save method.

Let us write one more class called Preferences that deals with various communication and website preferences of the customer.

<?php
class Customer
{

    protected 
$_name;
    protected 
$_street;
    protected 
$_city;
    protected 
$_country;

    public function 
setName($name)
    {
        
$this->_name $name;
    }

    public function 
setStreetAddress($street)
    {
        
$this->_street $street;
    }

    public function 
setCity($city)
    {
        
$this->_city $city;
    }

    public function 
setCountry($country)
    {
        
$this->_country $country;
    }

    public function 
save()
    {
        echo 
"Customer information saved";

    }

    
    public function 
getPreferences()
    {
        
// Create the customer preferences object
        
$preferences = new Preferences;
        return 
$preferences;
    }
}

class 
Preferences
{

    public function 
isCallOptIn()
    {
       
// Determine whether the customer has opted in to be called by our staff
        
return true;
    }
}

?>

In the Customer class, the method getPreferences() returns the Preferences object. To determine whether a customer has opted in to be called by our staff, we use the following snippet.

<?php
$customer 
= new Customer;
$preferences $customer->getPreferences();
$isOptIn $preferences->isCallOptIn();
?>

Consider the change in the calling code snippet.

<?php
$customer 
= new Customer;
$isOptIn $customer->getPreferences()->isCallOptIn();
?>

We know $customer->getPreferences() returns the preferences object. To call the isCallOptIn() method of the preferences object, we don't have to store the preferences object in a variable. We can use it in an expression.

Let's go back and improve our Customer class a bit.

<?php
class Customer
{
    protected 
$_name;
    protected 
$_street;
    protected 
$_city;
    protected 
$_country;

    public function 
setName($name)
    {
        
$this->_name $name;
        return 
$this;
    }

    public function 
setStreetAddress($street)
    {
        
$this->_street $street;
        return 
$this;
    }

    public function 
setCity($city)
    {
        
$this->_city $city;
        return 
$this;
    }

    public function 
setCountry($country)
    {
        
$this->_country $country;
        return 
$this;
    }

    public function 
save()
    {
      
// Save the information to a database
        
echo "Customer information saved";
    }
}
?>

In our improved Customer class, all methods but save() now returns the current object.

<?php
return $this;
?>

With the changes to the Customer class, the calling code can become interesting.

<?php
$customer 
= new Customer;

$customer->setName('James Bond')
         ->
setStreetAddress('Abc street')
         ->
setCity('London')
         ->
setCountry('England')
         ->
save();
?>

This is known as the fluent interface in PHP.

Notice we have only two statements in our latest client code. If you were to put up the second statement in one line, it will look like

<?php
$customer
->setName('James Bond')->setStreetAddress('Abc street')->setCity('London')->setCountry('England')->save();
?>

Here's a real world example of fluent interface usage. The following code snippet is obtained from Zend_Mail component manual page of the Zend Framework.

<?php
$mail 
= new Zend_Mail();
$mail->setBodyText('This is the text of the mail.')
    ->
setFrom('somebody@example.com''Some Sender')
    ->
addTo('somebody_else@example.com''Some Recipient')
    ->
setSubject('TestSubject')
    ->
send();
?>

About the author

Sudheer is an entrepreneur and software developer. Get more from Sudheer on Twitter.


Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>. The supported tag styles are: <foo>, [foo].

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Image CAPTCHA
Enter the characters shown in the image.