Home  >  Article  >  Backend Development  >  Inversion of control principle, what is its connection with dependency injection

Inversion of control principle, what is its connection with dependency injection

齐天大圣
齐天大圣Original
2020-08-12 10:47:281644browse

Inversion of Control (IOC)

First, let’s look at an example.

class Person
{
   private $name = '';
   private $age = 0;

   public function __construct(string $name, int $age)
   {
       $this->name = $name;
       $this->age = $age;
   }

   public function eat ()
   {
       echo '吃东西' . PHP_EOL;
   }

   public function drink ()
   {
       echo '喝水' . PHP_EOL;
   }

   public function sleep ()
   {
       echo '睡觉' . PHP_EOL;
   }

   public function wakeup ()
   {
       echo '起床' . PHP_EOL;
   }

   public function drive ()
   {
       echo '开车' . PHP_EOL;
   }

   public function wash ()
   {
       echo '洗漱' . PHP_EOL;
   }
}

Xiao Ming now needs to go to work when he wakes up in the morning, so Xiao Ming needs to do the following things

$person = new Person('小明', 24);
$person->wakeup();
$person->wash();
$person->eat();
echo '带上车钥匙、手机、电脑' .PHP_EOL;
$person->drive();

The above process is controlled by the programmer himself. Now, let's find a way to let the framework control the process. We add a new method in the Person class, the code is as follows:

public function work (callable $bring)
{
    $this->wakeup();
    $this->wash();
    $this->eat();
    $bring();
    $this->drive();
}

Xiao Huang also needs to go to work. Now he only needs to install the framework's guidance to complete the action of going to work.

$person = new Person('小黄', 29);
$person->work(function ()
{
    echo '带上手机、车钥匙、文件' . PHP_EOL;
});

The modified code has completed the inversion of control. In the previous code, the entire work process was controlled by the programmer, but in the modified code, the framework controls the work process. The flow control of the program is "reversed" from the programmer to the framework.

Now we can give the definition of inversion of control:

In fact, inversion of control is a relatively general design idea, not a specific implementation method, and is generally used for guidance. Framework level design. The "control" mentioned here refers to the control of the program execution flow, while "inversion" refers to the programmer controlling the execution of the entire program before using the framework. After using the framework, the execution flow of the entire program is controlled through the framework. Control of the process is "reversed" from the programmer to the framework.

Dependency injection

Inversion of control is a design idea, while dependency injection is a specific coding technique, and dependency injection is the implementation The most common technique for inversion of control. Dependency injection looks "high-end", but it is actually very easy to understand and master.

So what exactly is dependency injection? We can summarize it in one sentence: instead of creating dependent class objects inside the class through new(), instead, after the dependent class objects are created externally, they are passed (or injected) through constructors, function parameters, etc. class use.

Let’s look at an example:

interface Log
{
   function write (string $msg);
}

class TextLog implements Log
{
   public function __construct($dirname, $txtname)
   {
       $this->makeDir($dirname);
       $this->mkTxt($txtname);
   }

   private function makeDir (string $dirName) :void
   {
       // do something
   }

   private function mkTxt (string $txtName) :void
   {
       // do something
   }

   public function write (string $msg)
   {
       // do something
   }
}

class RedisLog implements Log
{
   private $redis = null;
   private $key = '';

   public function __construct(string $key)
   {
       $this->redis = '...'; // 获取redis实例
       $this->key = $key;
       // ...
   }

   public function write (string $msg)
   {
       // do something
   }
}

class App
{
   public function run ()
   {
       // do something

       // 记录日志
       (new RedisLog('log'))->write('框架运行信息记录');
   }
}

As you can see, the App class depends on the RedisLog class. If we no longer use redis to record days in the future, but instead use text files, then we need Modify the code in run.

Now, we switch to using the dependency injection technique to rewrite, the code is as follows;

class App
{
   private $logHandle = null;

   public function __construct(Log $log)
   {
       $this->logHandle = $log;
   }

   public function run ()
   {
       // do something

       // 记录日志
       $this->logHandle->write('框架运行信息记录');
   }
}

The rewritten App class no longer depends on the RedisLog class, and can be replaced with other Log classes at any time. As long as the class implements the write method. As you can see, dependency injection can flexibly replace dependent classes. In addition, it is the most effective way to write testable code.

There is an article about dependency injection in Zhihu. It is very easy to understand. You can also read it. The link is as follows:

A brief discussion on inversion of control and dependency injection https://zhuanlan.zhihu.com/p/33492169

The above is the detailed content of Inversion of control principle, what is its connection with dependency injection. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn