Applying SOLID principles

As a programmer, have you ever seen before classes (if they exists) with so much responsabilities, high coupled and other creepiest things? If you say:

“Yes, I’m suffering about that, please help me!”

For that SOLID was created!

In 2000’s, Michael Feathers introduces into development community the famous SOLID, in which it aims to be principles to guide us in our code design process. Instead, design pattern are Built-in blocks, SOLID are just guidelines.

But after all, what’s it SOLID?

SOLID is an acronym for (Single Responsibility, Open-closed, Liskov Substitution, Interface Segregation, Depedency Inversion), that are 5 principles object-oriented design by Uncle Bob, first let’s start with the “S” of SOLID.

Single Responsibility (SRP)

The Single Responsibility Principles says:

A class should have one and only one reason to change.

See the example below:

<?php

class MyController extends BaseController
{

    public function index()
    {
        $results = MyModel::where(['foo' => 1]);

        return View::make('my-view.index', compact('results'));
    }
}

What are the responsabilities of my controller?

  • Build and perform a query into database.

This means that:

  • If I change the query, I have to move on my controller.
  • If I change the database source that I was consulting before, I have to move on my controller.

Soon, this code violates Simple Responsibility Principle.

Smells

To be easy identify when your classes are breaking SRP, you may wonder:

What would be the responsibility of that class?

Stay tuned if you try to using any kind of connectors, for example:

“and”, “but also”

This is a strong hint that your class are doing so much.

Refactoring

One possible refactoring could be, extracting the database query from the controller using a repository pattern.

src/MyController.php

<?php

...

class MyController extends BaseController
{
    function __construct(Repository $repo) {
        $this->repo = $repo;
    }

    public function index()
    {
        $results = $this->repo->getAllFoo();

        return View::make('my-view.index', compact('results'));
    }
}

src/Repository.php

<?php

class Repository
{
    public function getAllFoo()
    {
        return MyModel::where(['foo' => 1]);
    }
}

Conclusion

Honestly, simple apply the SRP you will fell an improvement in your application design. Clearly this is not the end, still exists the other 4 principles, however they are well co-related.

Guilherme Guitte

Read more posts by this author.

São Paulo, Brasil http://www.guitte.org