Coding methods and principles (part 1)


During the course of this series we will look into the following coding methods/principles:

  • Dependency Injection
  • Coding to an Interface
  • Inversion of Control
  • Automatic Resolution

I will explain what each one means, why we should use them, and how to implement each one.

Dependency injection, coding to an interface, and inversion of control work well together so I will discuss those three first, and by the end of it, I will give you a full code example of the three working in conjunction with each other.

I will then finally give a brief explanation of Automatic Resolution and how it can be used as an alternative method to Dependency Injection and Inversion of Control.

Dependency Injection

So what exactly is dependency injection? It seems to be mentioned a lot in coding forums and coding practice web sites but the name of it alone scares a lot of people off from using it within their own applications. However, it is in fact a very simple method to implement.

The basic idea is instead of having your objects create a dependency, you pass through the dependency using the magic constructor method (constructor injection) or using setter methods (setter injection).

If you haven’t heard or implemented this method before, then chances are you will be creating new class objects within other classes.

Let me show you an example:

Imagine we had two classes, one called ‘ford’ and one called ‘engine’ and we want to display the ford’s top speed.

To achieve this, the ford class will require two main things:

  1. The cars top speed is determined by its engine, so first of all the ford will require an engine
  2. Secondly, it will need a method to retrieve the cars top speed from its engine instance

So with that in mind, lets take a look at our ford and engine class.

[php]

class ford{

private $engine;

public function __construct(){

$this->engine = new Engine;

}

public function getTopSpeed(){

return $this->engine->topSpeed()

}

}

class engine{

public function topSpeed(){

return ‘130 mph’;

}

}

[/php]

As you can see, the private engine property of the ford class gets set as a new engine instance within the constructor as soon as the class is created.

The Fords getTopSpeed method then uses its engine instance and topSpeed method to retrieve the fords top speed.

To display the fords top speed we then write the following code:

[php]

$ford_car = new ford();

$fords_top_speed = $ford_car->getTopSpeed();

echo $fords_top_speed;

//Displays: 130 mph

[/php]

Imagine that we now want to add a new car class ‘Honda’ and we want to display the top speeds for both the Ford and the Honda.

[php]

class honda

{

     private $engine;

     public function __construct(){  

          $this->engine = new Engine();

     }

     public function getTopSpeed(){

return $this->engine->topSpeed();

}

}

$honda_car = new honda();
$ford_car = new ford();

$hondas_top_speed = $honda_car->getTopSpeed();
$fords_top_speed = $ford_car->getTopSpeed();

echo $hondas_top_speed;
echo $fords_top_speed;

//Displays: 130 mph 130 mph

[/php]

This code works exactly as we would expect, so why is it an issue?

The main issue with this is that each car class (Ford, Honda) relies/depends on another class (the engine class).

The common term for this is that the code is tight coupled. So we need to decouple it.

But why do we need to decouple it?

Well imagine if the engine class either changes its name, for example to car_engine, or if the engine class required new arguments to be passed in to its constructor.

Or even both.

For example, imagine if our engine class now looked like this:

[php]

class car_engine{

private $fuel_type;

public function __constructor($fuel_type){

$this->fuel_type = $fuel_type;
}

public function topSpeed(){

return ‘130 mph’;
}

}

[/php]

The issue in this example and why we should decouple it is because changing the way the engine class is instantiated such as the name of the class or its constructor arguments means all the other classes that depend on it will break.

We would then have to modify all our car classes that are dependent on the engine class and change how they get instantiated.

This may seem like a two second job in our example, but in a real world example where you may have lots of classes that have lots of different dependencies, changes like this could make your code very hard to maintain.

How to fix the issue

This is where Dependency Injection can help decouple your code and makes sure that no class relies/depends on any other class.

Dependency injection solves this by inserting the dependencies through the constructor of the dependent class. As mentioned before, this is known as ‘Constructor Injection’. This then results in loosely coupled and highly maintainable code.

Below demonstrates this by changing our original code:

[php]

class honda

{

private $engine;

public function __construct(engine $engine){

$this->engine = $engine;

}

public function getTopSpeed(){

return $this->engine->topSpeed();

}

}

class ford

{

private $engine;

public function __construct(engine $engine){

$this->engine = $engine;

}

public function getTopSpeed(){

return $this->engine->topSpeed();

}

}

class engine{

public function topSpeed(){

return ‘130 mph’;

}

}

[/php]

As you can see the only difference in the dependent classes is that instead of creating a new instance of engine within the class, we pass through the instance in the constructors argument along with a type hint so we ensure only the correct class instance gets passed through. We then set the car classes’ engine property to be the instance that was passed through.

The engine class doesn’t change.

Then to display the top speeds we modify the main code to be the following:

[php]

//instantiated the engine class outside of any other classes
$engine = new engine();

//and pass it through as an argument
$honda_car = new honda($engine);
$ford_car = new ford($engine);

$hondas_top_speed = $honda_car->getTopSpeed();
$fords_top_speed = $ford_car->getTopSpeed();

echo $hondas_top_speed;
echo $fords_top_speed;

//Displays: 130 mph 130 mph

[/php]

Now we have made these quick and simple changes, our classes are no longer dependent on each other (no longer tight coupled). The outside system keeps complete control, as should be the case.

In the next tutorial in this series we will carry on looking at dependency injection but show a more practical example using database connections/orms rather than cars and engines. We will also look at some issues that can arise when using dependency injection and how we can solve them with Inversion of Control (IoC).