in object oriented programming design pattern cleanc code programming php solid ~ read.

Dependency Inversion

In this post we are going to talk about one of the most important topics for object oriented programming, at least for me it is the most important one.

  1. Dependency Inversion
  2. Inversion of Control
  3. Dependency Injection

All of the these is about how to make your code loosely couple. You might ask why it is better for my code to be loosely couple? Have you had the situation where one change you made effect the other code to break? Loosely Couple means that each part of your code shouldn't know the other part to do the job in order to make sure that there is no dependency on them.

Dependency Inversion

Here is some definition regarding Dependency Inversion - Dependency inversion is a specific form of decoupling where you decouple the higher levels of your system from the lower levels by separating them into libraries and using interfaces. This allows you to replace lower level parts of your system without major rework. Let's look at the following diagram.

High Level Class and Low Level Class, they don't depend on each other, instead the direction of dependency has changed that both of them depend on an Interface which means the change of classes only effect the interface which is a lot easier to deal with since interfaces don't have implementation details.

Inversion of Control

Inversion of control is a design principle used by framework libraries that allow the framework to regain some control from the application.

In other words, it is a generic term meaning rather than having the application, call the methods in a framework, the framework calls implementations provided by the application.

Like the difference between Library & Framework where we call invoke methods from Library while Framework invokes classes from our code.

Library - we call you
Framework - they call us

Enough of talking here, let's have a look at the code.

More comparison between DI & IoC
link1 link2

Dependency Injection

Ok finally enough of talking, let's get into some code. So how are we suppose to make sure our code is loosely couple by implementing Inversion of Control?

Here are generally three forms of implementation of Inversion of Control.

  1. Constructor Injection
  2. Setter Injection
  3. Interface Injection

Let's dive into each one of them in PHP

<?php  
  interface ICreditCard {
    public function pay();
  }

  class Visa implements ICreditCard
  {
    public function pay()
    {
      echo 'Pay by Visa Card';
    }
  }

    class Person {
        private $creditCard;

    public function __construct(ICreditCard $creditCard)
    {
      $this->creditCard = $creditCard;
    }
    }

  $creditCard = new Visa();
  $person = new Person($creditCard);
?>

(Constructor Injection)

This is the most common seen dependency injection here where we put the dependency of one class into another class via its constructor.

<?php  
  interface ICreditCard {
    public function pay();
  }

  class Visa implements ICreditCard
  {
    public function pay()
    {
      echo 'Pay by Visa Card';
    }
  }

    class Person {
        public $creditCard;

    public function getCreditCard()
    {
      return $this->creditCard;
    }

    public function setCreditCard($creditCard)
    {
      $this->creditCard = $creditCard;
    }
    }

  $creditCard = new Visa();
  $person = new Person();

  $person->setCreditCard($creditCard);
?>

(Setter Injection)

The last one which is a little rare most of the time will be the injection via Interface.

<?php  
  interface ICreditCard {
    public function pay();
  }

  class Visa implements ICreditCard
  {
    public function pay()
    {
      echo 'Pay by Visa Card';
    }
  }

    class Person implements IDependOnCreditCard {
        public $creditCard;

    public function inject($creditCard)
    {
      $this->creditCard;
    }
    }

  interface IDependOnCreditCard
  {
    public function inject(ICreditCard $creditCard);
  }

  $creditCard = new Visa();
  $person = new Person();

  $person->inject($creditCard);
?>

(Interface Injection)

So the above three ways are the most common way to inject dependencies.

End

Hope you guys have a better understanding of DI, once you pay attention to it it is everywhere in your programming life.

comments powered by Disqus