Reusing Implementation – a Walk-through of Inheritance, Composition, and Delegation

If had to give a convincing reason why most developers are such peculiar creatures, I’d say that every time you call them lazy, they feel insanely proud of themselves and show off a big “full teeth” smile. While admittedly the fact itself doesn’t go any further than being merely curious and anecdotal, it suggests the term “lazy” isn’t considered offensive. Of course, being a developer myself, I’d say that we’re not that insane (or at least that our insanity is generally pretty innocuous). It’s just that we take the word “lazy” as an ad-hoc synonym for “a really DRY person who cleverly reuses things” (hence doing less work).

While there’s nothing inherently wrong with having this attitude, described as the principle of least effort, sometimes it’s nothing more than a bluff. We know that taking advantage of framework A along with the generously functionality offered by library B can be remarkably productive when it comes to dealing with tight deadlines and generating revenue, but in the end all we really want is to avoid suffering the painful effects of code duplication and enjoy the blessings of a reusable implementation. Let’s be honest… do we really know if the frameworks or libraries in question are as DRY as they claim? Worse, assuming that they are, are we actually capable of writing DRY code on top of such codebases?

The popular belief is that reusing implementation, thus producing DRYer code, boils down to exploiting the benefits that Inheritance provides, right? Well, I wish it was that easy! There are few practitioners of cargo cult programming who will also add their loud voices claiming that Composition is actually the king of code reuse and that Inheritance should be thrown out. Or, why don’t we just stop cranking and get rid of both by picking up plain Delegation instead? It is an itching dilemma indeed, but ultimately pointless.

As one might expect, each approach has its own comfort zone, and which one fits the bill best depends on the type of problem being tackled along with its surrounding context. Inheritance has been an overrated beast for a long time, especially in the world of PHP, where central OOP concepts like the Liskov Substitution Principle (LSP) were viewed pretty much as tangled, obscure paradigms with little or no applicable value in the real world. On the flip side, Composition and Delegation have found quite a prolific niche in the language, reinforced by the momentum gained by Dependency Injection in the last few years. It’s as if opposing forces are constantly pushing against each other in order to maintain a purely fictional balance.

If you don’t know what path to travel when it comes to reusing implementation, in this article I’ll be doing a humble walk-through on the Inheritance/Composition/Delegation trio in an attempt to showcase, side by side, some of their most appealing virtues and clunky drawbacks.

Treading Inheritance’s Path – Simplicity vs Basetype/Subtype Issues

It shouldn’t be breaking news that the first code reuse approach I plan to put in the spotlight first is the most overused and misused of all, Inheritance. But I don’t want to be a sadist and bore you to tears (and myself, of course) explaining how to get a nice Dog subclass up and running by inheriting from Animal (ouch!). Rather, I’ll be a little more realistic and we’ll sink our teeth into a naïve, yet functional, PDO adapter. Here we go:

<?php
namespace LibraryDatabase;

interface DatabaseAdapterInterface
{
    public function executeQuery($sql, array $parameters = array());
}
<?php
namespace LibraryDatabase;

class PdoAdapter extends PDO implements DatabaseAdapterInterface
{
    protected $statement;
    
    public function __construct($dsn, $username = null, $password = null, array $options = array()) 
    {
        // fail early if the PDO extension is not loaded
        if (!extension_loaded("pdo")) {
            throw new InvalidArgumentException(
                "This adapter needs the PDO extension to be loaded.");
        }
        // check if a valid DSN has been passed in
        if (!is_string($dsn) || empty($dsn)) {
            throw new InvalidArgumentException(
                "The DSN must be a non-empty string.");
        }
        // try to create a valid PDO object
        try {
            parent::__construct($dsn, $username, $password,
                $options);
            $this->setAttribute(PDO::ATTR_ERRMODE,
                PDO::ERRMODE_EXCEPTION);
            $this->setAttribute(PDO::ATTR_EMULATE_PREPARES,
                false);
        
        }
        catch (PDOException $e) {
            throw new RunTimeException($e->getMessage());
        }
    }
    
    public function executeQuery($sql, array $parameters = array())
    {
        try {
           $this->statement = $this->prepare($sql);
           $this->statement->execute($parameters);
           return $this->statement->fetchAll(PDO::FETCH_CLASS,
               "stdClass"); 
        
        }
        catch (PDOException $e) {
            throw new RunTimeException($e->getMessage());
        }
    }
}

When it comes to creating a quick and dirty adapter that just adds some extra functionality to the one provided by the PDO class, Inheritance is indeed a pretty tempting path. In this case, the adapter performs some basic validation on the inputted database arguments and its executeQuery() method allows us to run parameterized queries via an easily consumable API. The following snippet demonstrates how to drop the adapter into client code to pull in a few users from the database:

<?php
use LibraryLoaderAutoloader,
    LibraryDatabasePdoAdapter;
    
require_once __DIR__ . "/Library/Loader/Autoloader.php";
$autoloader = new Autoloader;
$autoloader->register();

$adapter = new PdoAdapter("mysql:dbname=mydatabase",
    "myfancyusername", "myhardtoguesspassword");

$guests = $adapter->executeQuery("SELECT * FROM users WHERE role = :role", array(":role" => "Guest"));

foreach($guests as $guest) {
    echo $guest->name . " " . $guest->email . "<br>";
}

There are no smelly signs of any “incidental” breakages of the LSP, meaning that any instance of PdoAdapter could be safely swapped out at runtime by a base PDO object without complaints from the client code, and the adapter has been blessed with all the legacy functionality encapsulated by its parent. Can we dare to ask for a better deal?

Admittedly, there’s a catch. While not explicit, PdoAdapter is actually exposing to the outside world the whole verbose PDO API, plus the one implemented on it’s own. There might be occasions where we want to avoid this, even if the “IS-A” relation between PdoAdapter and PDO is neatly maintained.

We could appeal to the wisdom of the mantra “favor Composition over Inheritance” in such situations and effectively shift into the seas of Composition. In doing so, we would be effectively reusing PDO’s implementation, but without having to deal with its entire API. Better yet, since there wouldn’t be a “IS-A” relationship, but instead a “HAS-A” one between the corresponding adapter and the PDO class, we’d be also satisfying our purist OOP instincts. Encapsulation would keep its pristine shell intact.

Of course, one nice way to understand the inner workings of this approach is by setting up a concrete example. Let’s tweak the previous PdoAdapter class to honor the commandments of Composition.

Composition over Inheritance – of Adapters, Adaptees, and Other Funny Facts

Contrary to popular opinion, it’s ridiculously easy to implement a PDO adapter that rests on the pillars of Composition. Furthermore, the whole refactoring would be limited to just creating a simple wrapper which would inject a native PDO object into the constructor. Once again, a hands-on example is the best teacher when it comes to understanding the driving logic of the process:

<?php
namespace LibraryDatabase;

interface DatabaseAdapterInterface
{
    public function executeQuery($sql, array $parameters = array());
}
<?php
namespace LibraryDatabase;

class PdoAdapter implements DatabaseAdapterInterface
{
    protected $pdo;
    protected $statement;
    
    public function __construct(PDO $pdo) 
    {
        $this->pdo = $pdo;
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE,
            PDO::ERRMODE_EXCEPTION);
        $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,
            false);
    }
    
    public function executeQuery($sql, array $parameters = array())
    {
        try {
           $this->statement = $this->pdo->prepare($sql);
           $this->statement->execute($parameters);
           return $this->statement->fetchAll(PDO::FETCH_CLASS,
               "stdClass"); 
        }
        catch (PDOException $e) {
            throw new RunTimeException($e->getMessage());
        }
    }
}

While the refactored version of the adapter follows in general the formal definition of the Adapter pattern, the adaptee passed along into the adapter’s internals is, in this case, a concrete implementation rather than an abstraction. Considering that we’re attempting to design a slimmed down API for a PDO object, it doesn’t hurt to be pragmatic and inject the object directly in question without having to go through the hassle of defining an extra interface. If you feel a little more comfortable picking up the interface-based approach, just go ahead and stick to it all the way.

Leaving out of the picture those subtle implementation details, by far the most relevant thing to point out is the PdoAdapter class is now is a less verbose creature. Using Composition, it hides the whole PDO API from the outside world by exposing only its executeQuery() method to client code. Although naïve, the example raises a few points worth noting. First, the burden of dealing with potentially dangerous class hierarchies, where subtypes might behave wildly different from their base types blowing away application flow, has quietly vanished in thin air. Second, not only now is the adapter’s API less bloated, it declares an explicit dependency on a PDO implementation, which makes it easier to see from the outside the collaborator it needs to do its thing.

Yet this slew of benefits come with a not-so-hidden cost: in more realistic situations, it might be harder to create “composed” adapters than it is to create “inherited” ones. The correct path to tread will vary from case to case; be rational and choose the one that fits your requirements the best.

If you’re wondering how to get things rolling with the refactored PdoAdapter class, the following example should be instructive:

<?php
$pdo = new PDO("mysql:dbname=mydatabase",
    "myfancyusername", "myhardtoguesspassword");
$adapter = new PdoAdapter($pdo);

$guests = $adapter->executeQuery("SELECT * FROM users WHERE role = :role", array(":role" => "Guest"));

foreach($guests as $guest) {
    echo $guest->name . " " . $guest->email . "<br>";
}

By now we’ve seen at a very broad level two common approaches that can be employed for reusing implementation. So, what comes next? Well, I promised to dig deeper into the niceties of Delegation, too. While admittedly Composition is an implicit form of Delegation, in the earlier example the delegation link was set by declaring a dependency on a PDO implementation in the constructor.

It’s feasible, however, to get a decent delegation mechanism up and running by using one or multiple factory methods, even though this misses much of the advantages of decoupling interface from implementation. Regardless, it’s worth looking at this approach as it comes in helpful for building PDO adapters capable of lazy connections to the database.

Deferring Database Trips through Delegation

Can anything be more delightful than delaying an expensive database trip to the last minute? Avoiding it completely would certainly be better, which is the prime reason why cache system live and breath. But unfortunately, we just can’t have it all sometimes and we need to settle ourselves by designing PDO adapters that encapsulate this nifty ability inside the boundaries of a factory method.

Delegation is a simple yet powerful pattern that allows to implement this feature without much hassle. If we would turn our attention to the previous PdoAdapter class and make it exploit the benefits of Delegation, it would look as follows:

<?php
namespace LibraryDatabase;

interface DatabaseAdapterInterface
{
    public function connect();

    public function disconnect();

    public function executeQuery($sql, array $parameters = array());
}
<?php
namespace LibraryDatabase;

class PdoAdapter implements DatabaseAdapterInterface
{
    protected $config = array();
    protected $connection;
    protected $statement;
    
    public function __construct($dsn, $username = null, $password = null, array $options = array())
    {
        // fail early if the PDO extension is not loaded
        if (!extension_loaded("pdo")) {
            throw new InvalidArgumentException(
                "This adapter needs the PDO extension to be loaded.");
        }
        // check if a valid DSN has been passed in
        if (!is_string($dsn) || empty($dsn)) {
            throw new InvalidArgumentException(
                "The DSN must be a non-empty string.");
        }
        $this->config = compact("dsn", "username",
            "password", "options");
    }
    
    public function connect()
    {
        if ($this->connection) {
            return;
        }
        try {
            $this->connection = new PDO(
                $this->config["dsn"], 
                $this->config["username"], 
                $this->config["password"], 
                $this->config["options"]
            );
            $this->connection->setAttribute(PDO::ATTR_ERRMODE,
                PDO::ERRMODE_EXCEPTION);
            $this->connection->setAttribute(
                PDO::ATTR_EMULATE_PREPARES, false);
        }
        catch (PDOException $e) {
            throw new RunTimeException($e->getMessage());
        }
    }
    
    public function disconnect()
    {
        $this->connection = null;
    }
    
    public function executeQuery($sql, array $parameters = array())
    {
        $this->connect();
        try {
           $this->statement = $this->connection->prepare($sql);
           $this->statement->execute($parameters);
           return $this->statement->fetchAll(PDO::FETCH_CLASS,
               "stdClass"); 
        }
        catch (PDOException $e) {
            throw new RunTimeException($e->getMessage());
        }
    }
}

If you’ve ever had the chance to craft your own PDO masterpiece from scratch, or if you’ve just reused one of the heap available in the wild, the underlying logic of the above adapter should be pretty easy to grasp. Unquestionably, its most engaging facet is the implementation of the connect() method, as its responsibility is to create a PDO object on request which is then used in turn to dispatch queries against the database.

While admittedly this is pretty dull and boring, it’s helpful for showing how to use a sort of “hard-coded” Delegation in the implementation of adapters which are clever enough for triggering lazy connections to the database. Furthermore, the example below demonstrates how to put the adapter to use:

<?php
$adapter = new PdoAdapter("mysql:dbname=mydatabase",
    "myfancyusername", "myhardtoguespassword");

$guests = $adapter->executeQuery("SELECT * FROM users WHERE role = :role", array(":role" => "Guest"));

foreach($guests as $guest) {
    echo $guest->name . " " . $guest->email . "<br>";
}

Call me an unbearable pedantic if you want to, but consuming the adapter is actually a simple process, especially when analyzed from the client code’s standpoint. The major pitfall is that the adapter hides a dependency. This introduces a nasty coupling, hence making the whole implementation a little bit dirty. On the flip side, the adapter’s most appealing virtue rests with its capability for calling the database only when the situation warrants. Naturally, this sort of trade off can be worked out pretty easily by injecting a factory in the adapter, which would be charged with creating a PDO object when needed.

Even though this approach effectively is the best of both worlds, since it actively promotes the use of Dependency Injection while still employing Delegation, in my view it is somewhat overkill, at least in this case in particular.

Closing Thoughts

I have to admit that it’s rather challenging to come to a judgement on the flaws and niceties exposed by Inheritance, Composition and Delegation without falling into a shallow, shy analysis. Even so, taking the plunge is definitively worthwhile considering each approach is a central pillar of the OOP paradigm.

Moreover, while in this case I intentionally did an isolated “per approach” evaluation, something that hopefully was instructive in the end, it’s possible to wire up all the approaches together to implement more efficient code reuse strategies. There’s no mutual exclusion here.

Needless to say, it doesn’t make much sense to pile them up blindly just because you can. In all cases, be conscious and make sure to narrow their usage to the context you’re dealing with.

Image via Fotolia

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Tjorriemorrie

    Awesome, keep em comin like this and I’ll buy your book to say thank you :p

    • Alex Gervasio

      I’ll take your word for it :) . Thanks for the positive feedback.

  • http://www.mosheteutsch.com/ Moshe Teutsch

    Nice article.

    One thing, though: When re-throwing an exception, you should use the “next” property instead of just copying the message. For example:

    catch (PDOException $e) {
    throw new RuntimeException($e->getMessage());
    }

    Should be something like:

    catch (PDOException $e) {
    throw new RuntimeException(‘Error creating database connection’, null, $e);
    }

    Or, better yet, use a custom class:

    namespace LibraryDatabase;
    class ConnectionException extends RuntimeException {
    public function __construct($next = null) {
    parent::__construct(”, 0, $next);
    }
    }

    And throw it like so:

    catch (PDOException $e) {
    throw new ConnectionException($e);
    }

    • Alex Gervasio

      Hey,
      I rethrow exceptions like this, just to keep the snippets deliberately clean and uncluttered. In production, I usually appeal to a marker interface, which lets you catch both native and userland exceptions. Thanks for the feedback.

  • Rino André Johnsen

    Thanks again for a wonderful article. I would just like to add that, since I have been using a container that wraps a servicelocator for resolving requests to the container, the composition comes naturally, so the question to whenever or not using inheritances or composition has never been a question for me.

    • Alex Gervasio

      Hi Rino,
      Glad you enjoyed the article. In your particular situation, where (I guess) the SL is injected straight into the container’s internals and consumed accordingly, Composition/Aggregation is effectively the natural choice to pick up. In some other use cases, like the implementation of a PDO adapter, just to cite the example showcased in the article, making the right decision might not be so obvious. Taming the oddities of the is-a/has-a tandem, without ending up bastardizing its intrinsic nature, or breaking down some central OOP principles can be pretty tricky sometimes.

  • Dave Hulbert

    How about this for a rudimentary way of exposing the dependency?

    $adapter = new PdoAdapter(function() {
    return new PDO("mysql:dbname=mydatabase", "myfancyusername", "myhardtoguespassword");
    });

    • Alex Gervasio

      Hey Dave,
      IMO it’s a pretty creative one, even though I’m not a big fan of mixing up procedural programming with OOP, specially when it comes to doing dependency injection. Plus, the result of the closure should be stored in a property if you want to have a nice lazy instantiation of the PDO class. I definitively would declare the adapter’s dependency the “traditional” way, by type hinting an interface whenever possible. Thanks for the feedback.

    • http://www.andrejfarkas.com Andy

      IMHO this is kind of dependency is kind of tricky. You have no chance to know what to pass as a parameter to constructor. Like Alex said it is best to make your classes depend on an interface. So there’s some strong type-hinting applied.

      @Alex – very nice article. The more I do programming the more I like to use composition over inheritance whenever possible. It seems to me that inheritance is kinda of against OOP, which might make very little sense.

      • Alex Gervasio

        Thanks Andy for the kind words, and of course, for expressing so eloquently your thoughts about Inheritance. Sounds pretty much like a kinda catharsis, which is always therapeutic my friend :) While I do agree with you that Inheritance has its own pitfalls and gotchas, it’s a powerful pillar of OOP that deserves a respectful acknowledgment in the code reuse podium . As with many other programming stuff, it should be used with moderation and due caution, for sure, and switch over composition in all “applicable” use cases.

  • Joe Dempsey, Sr.

    Alejandro, you said: “Naturally, this sort of trade off can be worked out pretty easily by injecting a factory in the adapter, which would be charged with creating a PDO object when needed.” Which, I believe, is the most flexible of all the approaches mentioned and eliminates that nasty hidden PDO dependency.
    Also, in your writing for DevShed, I thought you were from Spain when all the while you were from Argentina! Thanks for yet another engaging and enlightening article. I will pass its URL along to my top “Intro Java” students who will appreciate some “food for thought”.

    • Alex Gervasio

      Hi Joe,
      Nice to hear from you again :) . Well, I’m glad to see the article has been instructive, considering the fact you’re planning to throw it at your students for some (hopefully) useful brainstorming experience. And yes, I’m effectively from Argentina, a nice country located further down in our beloved America (se habla español!). Thanks for the feedback.

  • Alex

    I just want to say thank you very much for your great work writing this up. I am very close to your homeland (from Peru) and I’m really proud these great material come from South America :). Did you have a book already?. If you do, please send me the link to buy it, no doubts I will enjoy it as I do with all your write ups. Thank you again!

    • Alex Gervasio

      Hey Alex,
      Greetings from Argentina! And thanks for the kind comments indeed. We have so much history in common with Peru. So far, I haven’t written a book, but mostly because I just can’t find enough time to tackle the task with due responsibility. Tight deadlines…you know. Maybe in the future I can draw interest from the great mates right here at Sitepoint and write a book on Domain Driven Design/PHP. Time will tell :)