Why you should always use PHP interfaces

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.

Tags: , , , , ,

23 Responses to “Why you should always use PHP interfaces”

  1. Alec Sammon says:

    Nice, succint and I agree!

  2. Erwin M. says:

    I disagree. Use interfaces if an interface is required or you are 100% sure that you need exchange the implementation.

    Why you can’t have your first point with a class instead of an interface? I don’t see how it helps to have an interface. Just restrict yourself to the single responsibility principle.

    For the second point, use a class and then if you really need this kind of flexibility you can later refactor out an interface very easy. In Eclipse there is a menu point, Extract Interface. It will create an interface and replace each concrete class reference with the interface reference. In PHP is far simpler then that. Php is dynamically typed. Even if your method takes a concrete class reference you can always exchange the implementation.

    But if you going to create always an interface your application’s code will become just bloated for no reason at all.

  3. Florian says:

    It can be very useful for Dependency injection too, or for the adapter pattern.

  4. Dave says:

    @Erwin M.
    I agree that you don’t *need* to use interfaces for good OO design. As you say, you can simply follow good practice (choose good abstractions, single responsibility etc..) I still always build interfaces for domain objects and furthermore I maintain the process of doing so helps get the design straight in my mind. I accept this is a personal preference.

    For the second point – yes you could go through and change lots of code if you ever need the flexibility (which you will for the pattern I described). Whether that happens via some handy IDE feature or not, you’re still changing lots of code. Using interfaces from the off avoids this. Secondly, I’m not sure what you mean by “exchange the implementation”. If you type-hint with class A you cannot pass in class B without PHP throwing a catchable fatal error. http://pastebin.com/gN8MCrjr

    Finally, I don’t think it adds “bloat” :)

  5. Imho interface usage is important for the Interface Segregation Principle: when you pass a concrete class in a method, it becomes dependent on all the public methods instead of just the ones it calls, which can be harvested in an intention-revealing interface.

  6. Dave says:

    Giorgio – this is a good point. One example where I use interface segregation is for “exportable” domain objects; these all implement a method “export” (which is a serialisation system of sorts). Wherever a method just needs something that is exportable it would type-hint with the exportable interface.

  7. roy simkes says:

    Interfaces generally look cool and I really agree with the idea of having interfaces which is a thing I try to do too.

    However you should notice that Interface concept has begun because of some “limitations” of statically typed languages. When passing a parameter you should define a type and a hard coded type would have been a pain and it will be hard to refactor it. And it also breaks an OO principle (I can’t remember it’s actual name but it was something about interchanging classes with each other). As there is no multiple inheritance in Java they have “invented” a thing like that. The reason PHP community does not talk a lot about Interface is this I guess. Because we are not depending on them for polymorphism but Java guys have do, a lot.

    Ruby guys says that “if an object acts like a duck, talks like a duck, then it’s a duck”. Just like PHP actually. You don’t need to explicitly define the object as a “duck”! You call the methods in a duck and if your object respond, that it’s actually a duck. I don’t care if it’s a dog or something else.

    As a conclusion I don’t mean that Interface is bad/needless. They are actually needed if you want to extend a usage, implement different “hows”, to put a guideline for an architecture or simply if you work with a team. Because developers generally tend to be lazy and they can forget how a duck acts or they might not even know what a duck is :)

  8. cryptocompress says:

    We simple violate the “Liskov substitution principle” without Interfaces! Thank you!

  9. Mark says:

    In #1 you point out good design principles, but I don’t understand what it has to do with interfaces versus classes. Looking at an object as a set of capabilities is a good idea, but doesn’t that apply as much to classes as it does to interfaces?

    Regarding #2, couldn’t you achieve the same advantage with subclassing? For example, if I have a method that accepts a User, and later I want to apply lazy loading logic to it, I can extend User into LazyUser, overload isMember, and pass that into the same function.

    I’m not arguing that interfaces are bad, by any means, but after reading the article I don’t understand why they should always be used.

  10. Wil Moore III says:

    >couldn’t you achieve the same advantage with subclassing

    Actually, you _could_; however, now you potentially have an object that has capabilities that it doesn’t/shouldn’t need. This also gets one into trouble should that object need further capabilities from elsewhere (since you’ve just spent your only “extends”). If there is no is-a relationship, sub-classing isn’t the best option.

  11. paul says:

    ok, im not scrodge, but the snowflakes are distracting as shit whilst your reading an article my eye is constantly caught by snowflakes floating down the page… :(

  12. paul says:

    ok, fixed it, disabled javascript :)

  13. Dave says:

    Yeah sorry about that. It was Christmas though. :|

  14. lasse manson says:

    Man, paul is sour :-P

    Cracked me up that little interchange.

  15. Pete says:

    I love thew way the ‘let me google that for you’ link returns this blog post at number two. Good job you actually answered the question properly or hundreds of would-be developers would be stuck in an infinite loop.

  16. foxy_rose says:

    totally agree with you. but for small systems – is an overkill.

  17. George Dawson says:

    I keep seeing the word “object” used as though it was interchangeable with “class”. For Instance, “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.”

    Shouldn’t this read “In practical terms, this means that a class is defined by the messages it can receive and send; the methods that handle these messages comprise the class’s sole interface to the outer world.”?

    Or am I wrong? I’d like to know.

  18. Dave says:

    An object is an instance of a class. To me it makes sense to think of an object being something that receives messages. Of course it is the class that defines the interface, but a class cannot receive messages, a class is just a prototype from which we can build an object.

  19. Aaron says:

    Currently I use interfaces to allow my team to collaborate on what we may or may not need in a class.

  20. Jeremy says:

    I’m overjoyed at finding some sanity in this php stuff. I’m all about using interfaces, as I enjoy constructing low level systems with various state machines to roster out duties. I’d be stuck if I couldn’t establish an interface pattern to allow inheritance and consistency across what might grow to hundreds of classes, that need to be swapped out of a stack. I’m sitting here with my head in modern functional php, thinking ideas rather not share, for shame! Suffice to say a search for delegate patterns brought me here. And I thought I should say thanks. I agree, to both major points. Why establish patterns when there are none, but why lock an object in as a class when you may need to extend it in various ways. I need some objects to have differing functionality, to throw a different exception for each one. If it was a concrete class, it would be like, ew. With an interface, I can even save some macros up in my IDE for the time I get this pattern down. Again, thank you for this. It was a great read!

  21. Timster at Home says:

    Simples – interfaces allow implementations to be decoupled. Using abstract classes or implementation inheritance makes for a tightly coupled system. Interfaces allow loose coupling.
    A dog can walk and so can a person and they are both mammals. But so can a lizard and a bug and they aren’t mammals. Ultimately they are all animals but a robot can walk as well and that’s not an animal. A snake is an animal but its doesn’t have legs so it cannot walk.
    OOP should be about behaviour not about data and “operations”.
    If we assume that to walk a thing needs legs then the legs could be part of the Walk interface. It doesn’t make sense to have a “number of legs” property on a base animal class because if you instantiate a worm or a fish the number of legs is zero? You can’t walk with zero legs so why include this as part of an objects behaviour.

  22. Frederik Krautwald says:

    Interfaces are absolutely brilliant in test-driven development, mocking and stubbing.

Leave a Reply