What is the Dependency inversion principle and how it is used in Magento 2?

This article will help you to understand the dependency inversion principle in Magento 2.

Dependency inversion principle means that the high-level classes are not working directly with the low-level classes, they are using interfaces as an abstract layer.

In this case, the instantiation of new low-level objects inside the high-level classes (if needed) cannot be done utilizing the operator new. Instead, some of the Creational design patterns can be used, such as the Factory Method, Abstract Factory, Prototype.

This principle should not be implemented blindly for every class or module. If we have a class functionality that is more likely to remain consistent in the future there is no need to apply this principle.

By injecting the (low-level) dependencies, and using interfaces or abstract classes as types, you open up each class to a broader range of possibilities, since each type can be replaced by different implementations.

  • The Manager class doesn't require any changes when adding SuperWorkers.
  • The risk to affect old functionality present in the Manager class is reduced as we don't modify it.
  • No need to revise the unit testing for the Manager class.

Example:

Below is the code which supports the Dependency Inversion Principle.

In this new design, a new abstraction layer is added through the IWorker Interface.

// Dependency Inversion Principle - Good example
interface IWorker {
public void work();
}

class Worker implements IWorker{
public void work() {
   // ....working
}
}

class SuperWorker  implements IWorker{
public void work() {
   //.... working much more
}
}

class Manager {
IWorker worker;

public void setWorker(IWorker w) {
worker = w;
}

public void manage() {
worker.work();
  }
}

Now we will see an example of the Model class in Magento2 module Aureatelabs/InventoryLog.

app/code/Aureatelabs/InventoryLog/Model/Movement.php

namespace Aureatelabs\InventoryLog\Model;

use Aureatelabs\InventoryLog\Api\Data\MovementInterface;

class Movement extends \Magento\Framework\Model\AbstractModel implements MovementInterface
{

   /**
    * @return void
    */
   protected function _construct()
   {
       $this->_init('Aureatelabs\InventoryLog\Model\ResourceModel\Movement');
   }

   /**
    * Get movement_id
    * @return string
    */
   public function getMovementId()
   {
       return $this->getData(self::MOVEMENT_ID);
   }

   /**
    * Set movement_id
    * @param string $movementId
    * @return \Aureatelabs\InventoryLog\Api\Data\MovementInterface
    */
   public function setMovementId($movementId)
   {
       return $this->setData(self::MOVEMENT_ID, $movementId);
   }
…..

}

Now for the interface,

app/code/Aureatelabs/InventoryLog/Api/Data/MovementInterface.php

namespace Aureatelabs\InventoryLog\Api\Data;

interface MovementInterface
{
   const MOVEMENT_ID = 'movement_id';
   
   /**
    * Get movement_id
    * @return string|null
    */
   public function getMovementId();

   /**
    * Set movement_id
    * @param string $movementId
    * @return \Aureatelabs\InventoryLog\Api\Data\MovementInterface
    */
   public function setMovementId($movementId);

}
  • Share :