jump to navigation

The basics of Fluent interfaces in PHP April 11, 2011

Posted by Tournas Dimitrios in PHP.
trackback

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
<?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 : 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
$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();

z

Comments»

No comments yet — be the first.

Leave a comment