Why Interfaces Rock

« »

When I first learned PHP 5’s object oriented syntax and rules, I didn’t see much of a point to the interface options. I felt that I could do more by defining abstract classes and at least filling in some of the methods with some details. Lots of people in the PHP world still aren’t 100% sure the reasons that interfaces exist, or the best way to use them. However, interfaces are very cool, and anyone who does OOP in PHP should know about them.

To start, what is an interface? An interface is a collection of completely abstract methods. Interfaces do not contain any of the innerworkings of the application; instead, they serve the sole purpose in setting a structure for the objects that implement them. All of their methods must be public. Here is a sample interface:

<?php

interface DatabaseI
{
    public function __construct();

    public function connect();

    public function query();
}

&#91;/sourcecode&#93;

That doesn't look very interesting at all, and it's not, until we start getting into <a href="http://us2.php.net/manual/en/language.oop5.typehinting.php">type hinting</a> and using <a href="http://us2.php.net/manual/en/language.operators.type.php">instanceof</a> in PHP 5. This is where the power of interfaces comes into play.

As a developer, I've often wished there was a way to know that an object - any object - had implemented certain methods. With type hinting and the instanceof operator, it is now possible to determine whether or not an object has those methods, and interfaces make this even easier. Take for example:



class withoutTypeHinting
{
    public function __construct($databaseO)
    {
        if(method_exists('connect') {
            $databaseO->connect();
        }
    }
}

// Now let's use typehinting from our previous example

class withTypeHinting
{
    public function __construct(DatabaseI $databaseO)
    {
        $databaseO->connect();
    }
}

What’s the difference there? In the first example, we’re hoping that the method exists so that we can call it. We’ll have to throw an exception or do something if the connection doesn’t actually exist. But in the second example, we’re demanding an object that has implemented the methods in DatabaseI. We know that these methods must have been implemented, because we’re getting an instantiated object. So the method must exist.

Interfaces make it much easier to predict what methods will be available, and also to ensure that subclasses still conform to some semblance of the structure you’ve defined.

Interfaces are not without their drawbacks. One huge drawback of interfaces is that you must implement them precisely as they are defined; that is, because our __construct() method contained no arguments, you must either make your __construct() argument contain no arguments or set each argument to a value (e.g. __construct($a = true, $b = false); // etc). When defining an abstract class, and abstract methods, the rules of inheritance apply, making it possible to redefine the argument list. Also, because you have not defined anything but the method signature, you have no way of forcing it to return a particular type. Finally, you may not build an interface containing protected methods; you must use an abstract class for this.

Still, interfaces rock. They allow you to enforce the type of object and the methods that must be defined, and with type hinting you can always feel confident that a method is implemented, regardless of how that interface is extended.

Brandon Savage is the author of Mastering Object Oriented PHP and Practical Design Patterns in PHP

Posted on 9/25/2009 at 1:00 am
Categories: PHP 5
Tags: , ,

Marcus K (@sunwukung) wrote at 9/25/2009 4:28 am:

The other cool thing is that any object that implements an interface also inherits it’s type – so you can make a consuming object accept objects of only one type (via typehinting) – but then make a whole suite of consumables with different class names that implement an interface of the type required by the consumer. VERY handy.

fqqdk (@fqqdk) wrote at 9/25/2009 6:02 am:

this is a fun syntax, too:

interface SomeMarker {}

class MarkedException implements SomeMarker {}

try {
throw new MarkedException;
catch(SomeMarker $ex) {
echo “isn’t it fun?”;
}

Brandon Savage (@brandonsavage) wrote at 9/25/2009 7:25 am:

I love the ability to type hint with exceptions. It makes catching different exceptions that share the same parent or implement the same interface so easy.

Giorgio Sironi (@giorgiosironi) wrote at 9/25/2009 11:32 am:

I probably won’t put a constructor in an interface since different implementations have different collaborators requirements. Commonly the creation of an object does not use polymorphism but it is abstracted away with a factory, since in many language you cannot do new $class(), and if you do it in php there is no type safety that the object will conform to an interface – type hinting for method parameters works only for already created objects.

the_disco wrote at 9/25/2009 11:39 am:

In software design this is called strategy pattern. It’s really cool that php5 really allows us to finally implement this paradigms.

Peter Warnock (@pwarnock) wrote at 9/25/2009 1:45 pm:

I love coding to the interface. They’re great for parallel development, too.

I can adopt or design an interface and hand it off to a team member to code the internals. Meanwhile, I know what methods have been exposed so that I can interact with it.

Interfaces help make objects more tangible. Think of your car stereo for example. If you go aftermarket, you have to buy an adapter to couple the interface of the stereo with the interface of the car’s wiring harness.

Objects become more reusable when you know the interface and can write an adapter to pair two objects together.

Ever Barreto (@everdaniel) wrote at 9/25/2009 4:51 pm:

Hi Brandon!

I just found this article today and your site looks also great (I’ve already added your feed to my Feedreader)… looking forward to read more posts!

Have a nice day,

Ever Daniel

Richard Harrison wrote at 9/25/2009 6:00 pm:

Another reason why I like interfaces is that methods which specify them as parameters are really easy to write unit tests for.

Implement the interface in the unit test case, add the methods with the return values that you want to check and then have the test method pass itself to the method to be tested.

Elegant, simple and reduces the need to mock objects.

Aaron Saray (@aaronsaray) wrote at 9/26/2009 12:25 am:

I use interfaces for plugin based architecture. When you use the type hinting that you specified (or ‘instanceof’), you can make sure that the plugin has at least defined the methods that your code requires. This way, when a user installs a new plugin, it at least won’t kill your software with a function not found type error. :)

fqqdk (@fqqdk) wrote at 9/26/2009 7:01 am:

@Richard Harrison: that is called Self Shunt Pattern. :) http://www.objectmentor.com/resources/articles/SelfShunPtrn.pdf

Jani Hartikainen (@jhartikainen) wrote at 9/26/2009 10:23 am:

I’ve been thinking of writing about interfaces as well. Good stuff, but perhaps a bit difficult to understand.

I have to agree with Giorgio in that your interface shouldn’t define the constructor – most languages don’t even let you – because classes implementing it often have different requirements and the constructor isn’t really a part of the object “surface”

Hari K T (@harikt) wrote at 9/26/2009 4:43 pm:

Great article Bradon . I like your comment box including the twitter username . Great one .

Harry Fuecks (@hfuecks) wrote at 9/26/2009 7:01 pm:

Good job explaining what interfaces do but I had to throw in the counter punch over at reddit – http://www.reddit.com/r/PHP/comments/9obg1/why_interfaces_rock/c0dmsj8 – PHP Interfaces Suck!

Brandon Savage (@brandonsavage) wrote at 9/26/2009 8:26 pm:

I’m pretty comfortable with who I am, and what I wrote. Feel free to counter-punch away. And you made some really good points.

Artur Ejsmont wrote at 9/28/2009 3:57 am:

Hi Harry, seriously, the punch was a total miss ;- )

After a while of using interfaces in PHP in larger projects that live for a while you will probably acknowledge the benefits.

Unless you work at facebook you wont have to worry about delay caused by interfaces resolving at runtime. Please lets not get back into micro optimizations path ever again.

PHP is not java nor other language, if you use for some time you will probably benefit from interfaces.

Karn Sakulsak (@semicolonth) wrote at 9/29/2009 4:55 am:

Thank you Brandon, you give me the light of Interface usage. After I think of it as a sub to Abstract concept.

« »

Copyright © 2023 by Brandon Savage. All rights reserved.