This post was sparked by a very simple question from an ex-colleague:
Why bother with PHP interfaces?
The subtext here was that the classes themselves contain the interface definition (through the methods they define) and hence interfaces are not needed, particularly where there is only one class that implements a given interface. One response to this question would be “hang on, let me Google that for you”. However the question got me thinking about how best to demonstrate the purpose and power of interfaces. Plus there isn’t that much good stuff out there about the use of PHP interfaces.
Why interfaces?
1. It helps you think about things in the right way
Object oriented design is hard. It’s usually harder for programmers, like myself, who started out in a procedural world. Allen Holub sums it up nicely in the primer section of his book Holub on Patterns (which includes much of this article from Javaworld) when he explains how people often think that an “object is a datastructure of some sort combined with a set of functions”. As Holub points out – this is incorrect.
First and foremost, an object is a collection of capabilities. An object is defined by what it can do, not by how it does it — and the data is part of “how it does it.” In practical terms, this means that an object is defined by the messages it can receive and send; the methods that handle these messages comprise the object’s sole interface to the outer world.
It’s a subtle distinction, especially for those of us with a procedural background. Thinking in terms of these messages is hard; in the same way that static methods in PHP and “God” objects seem so much more familiar. Making wide use of interfaces when building an application is an easy way of getting out of these bad habits.
When I’m trying to design an OO system I usually start with Cunningham and Beck’s CRC cards (Class, Responsibility, Collaboration). This approach involves writing down on a separate index card (or small piece of paper) the name of each class, what its responsibility is and which other classes it collaborates with. From here, I then define the public interface of each class (the methods that handle the messages it can send and receive).
Thinking in the right way is the biggest advantage of interfaces, because it is the hardest thing to get right.
2. It makes for more future-proof code
Having a separate interface for every domain object may at first seem like overkill. Why bother? One reason is the flexibility it gives you going forward. An example of this is the Virtual Proxy lazy-load pattern. This relies on a placeholder object having exactly the same interface as a real domain object. Whenever one of the Virtual Proxy’s methods is called, it will lazy-load the actual object itself and then pass the message through. Stefan Preibsh recently gave a talk that includes this pattern entitled “A new approach to object persistence” which is well worth a read.
The interesting thing here is that by making classes that collaborate with a given class rely only on interface rather than concrete class we can implement a Virtual Proxy pattern at any time, safe in the knowledge none of our application will break!
// this is good - userInterface is an interface name
public function sendReminder(userInterface $user)
{
// do something
}
// this is less good! user is a specific class implementation
public function sendReminder(user $user)
{
// do something
}
The following simple example shows the Virtual Proxy pattern in action.
// our interface
interface userInterface
{
public function isMember();
}
// our concrete user class
class user implements userInterface
{
private $paidUntil;
public function __construct($paidUntil)
{
$this->paidUntil = $paidUntil;
}
public function isMember()
{
return $paidUntil > time();
}
}
// our proxy
class userProxy implements userInterface
{
private $dao;
private $user;
private $userId;
public function __construct($dao, $userId)
{
$this->dao = $dao;
// set user to NULL to indicate we haven't loaded yet
$this->user = NULL;
}
public function isMember()
{
if ($this->user === NULL)
{
$this->lazyLoad();
}
return $this->user->isMember();
}
private function lazyLoad()
{
$this->user = $this->dao->getById($this->userId);
}
}
Now let’s assume we have some other part of our code that collaborates with the user object to find out if someone is a member.
class inviteList
{
public function add(userInterface $user)
{
if (!$user->isMember())
{
throw new youMustPayException('You must be a member to get an invite.');
}
// do something else
}
}
Our inviteList class does not care what type of object it receives (proxy or real), it simply requires something that implements userInterface.
The same argument holds true for the Decorator pattern; by programming to interface each collaborator doesn’t care which concrete implementation (the outer-most decorated layer) it is given, as long as it adheres to the right interface.
In a nut shell: always programme to interface.


