SOLID: Introduction

  • 16/03/2016
  • 4 minuten leestijd

SOLID: Introduction

A few weeks ago, I gave a presentation about the SOLID principles, which was quite popular. In fact, it was so popular that we had to close the RSVP on meetup a few days in advance, due to a lack of space. For future reference, we are working on streaming solutions for our technights, but this was not yet in place back then. For that reason, I decided to dedicate a 7-part blog to the principles, starting with the why of the SOLID principles.

SOLID principles, why should I care?

Lets start at the beginning, and wonder about why the SOLID principles are so important. To answer that question, we first have to ask ourselves a different –but related– question, one that every developer has asked at least once: what is this object oriented programming anyways?

The question does not have a simple answer. For example, consider the following example:

<?php
echo "Hello world";

Of course, this is not object oriented. Granted, you could claim it is, since the particular language you're using creates a String object from the declaration, but most developers would not agree. To make this simple example object oriented, you could simply encapsulate it in a class.

<?php
class Hello
{
    /**
     * Pretty trivial method
     */
    public function main()
    {
        echo "Hello world";
    }
}

(new Hello)->main();

So, is this object oriented? If you'd look for the definition, you might find one in which this code is OOP, but I would say it isn't. And for good reason; too often have I seen code of several hundreds –even thousands– of lines wrapped in a single method, just because the programmer heard of the concept of OOP and decided this was the easiest way of making his procedural code object oriented. Strictly speaking, they are correct, but most OO-programmers would nevertheless disagree.

So what should we do to make this code OOP after all? We could make our code more reusable...

<?php
class Hello
{
    /**
     * Slightly less trivial method
     *
     * @param string $something
     */
    public function main(string $something)
    {
        echo "Hello {$something}";
    }
}

(new Hello)->main("world");

... or add some local scope ...

<?php
class Hello
{
    /**
     * @var string
     */
    private $something = "world";

    /**
     * And a little bit more trivial
     */
    public function main()
    {
        echo "Hello {$this->something}";
    }
}

(new Hello)->main();

... use typecasting ...

<?php
class Hello
{
    /**
     * @var string
     */
    private $something;

    /**
     * Hello constructor.
     *
     * @param string $something
     */
    public function __construct(string $something)
    {
        $this->something = $something;
    }

    /**
     * This is getting silly...
     *
     * @return string
     */
    public function __toString()
    {
        return "Hello {$this->something}";
    }
}

echo new Hello('world');

... or even use various types of injection ...

<?php
class Hello
{
    /**
     * @var string
     */
    protected $something;

    /**
     * @var resource
     */
    protected $writer;

    /**
     * Hello constructor.

     * @param resource $writer
     */
    public function __construct($writer)
    {
        $this->writer = $writer;
    }

    /**
     * @param string $something
     * @return $this
     */
    public function setSomething(string $something)
    {
        $this->something = $something;
        return $this;
    }

    /**
     * OK, you've officially gone over the deep end,time to stop now!
     */
    public function main()
    {
        fwrite($this->writer, sprintf('Hello %s', $this->something));
    }
}

(new Hello(fopen('php://stdout', 'w')))->setSomething('world')->main();

And somewhere in between all of these examples, my code suddenly became object oriented. But when? The actual border between non-OO and OO appears to be more of a subjective line rather than an absolute one: if you ask 10 developers, you'll probably get 11 diffent answers.

To me, a large part of the answer lies in the SOLID principles. They are not called principles of object oriented design for nothing! They give you some generic guidelines about how to design your application such that you can call it object oriented. If you keep to them, your code will be easier to maintain and extend, both of which are goals set by OOP anyways, but not always achieved. The 5 principles are

Each will be handled in a separate post, followed by a wrap-up in the end, so you'll there's enough to read!

And yes, for those that just now noticed this, SOLID is a backronym, not unlike most acronyms in theoretical computer science. They are funny that way.