Talking about Inversion of Control and Dependency Injection

Chapter 1: Xiao Ming and his mobile phone

Once upon a time there was a man named Xiao Ming

Xiao Ming has three hobbies, smoking, drinking... Ahem, sorry, I went to the wrong studio. It should be visiting Zhihu, playing the king pesticide and grabbing WeChat red envelopes

Xiao Ming's three hobbies

We use a simple pseudo-code to create such a Xiaoming


class Ming extends Person
{
    private $_name;

    private $_age;

    function read()
    {
        //逛知乎
    }

    function  play()
    {
        //玩农药
    }

    function  grab()
    {
        //抢红包
    }

}


However, as a human being, Xiao Ming has no way to achieve the above functions by himself. He has to rely on a mobile phone, so he bought an iphone6, and then we will make an iphone6


class iPhone6 extends Iphone
{
    function read($user="某人")
    {
        echo $user."打开了知乎然后编了一个故事 \n";
    }

    function play($user="某人")
    {
        echo $user."打开了王者农药并送起了人头 \n";
    }

    function grab($user="某人")
    {
        echo $user."开始抢红包却只抢不发 \n";
    }
}


Xiao Ming cherishes his new mobile phone very much and keeps it firmly in his hand every day , so Xiao Ming has become like this


class Ming extends Person
{
    private $_name;

    private $_age;

    public function  __construct()
    {
        $this->_name = '小明';
        $this->_age = 26;
    }

    function read()
    {
        //……  省略若干代码
        (new iPhone6())->read($this->_name); //逛知乎
    }

    function  play()
    {
        //……  省略若干代码
        (new iPhone6())->play($this->_name);//玩农药

    }

    function  grab()
    {
        //……  省略若干代码
        (new iPhone6())->grab($this->_name);//抢红包

    }

}


Today is Saturday, and Xiao Ming doesn't have to go to work, so he got up, went to Zhihu in turn, played with the king of pesticides, and grabbed a red envelope.

$ming = new Ming();  //小明起床
$ming->read();
$ming->play();
$ming->grab();

At this time, we can see the output on the command line as follows

小明打开了知乎然后编了一个故事 
小明打开了王者农药并送起了人头 
小明开始抢红包却只抢不发

On this day, Xiao Ming had a very fulfilling life, and he felt that he was the happiest person in the world.


Chapter 2: Xiao Ming's happiness and sadness


Xiao Ming and his mobile phone spent a good time together. When he was free, he would hold his mobile phone, browse Zhihu, browse Weibo, and play games. He felt that he didn't need a girlfriend at all, as long as he had a mobile phone. Beside you, you are satisfied.

But who would have thought that the system update time and time again completely shattered his dreams, his mobile phone became more and more stuck, and the battery life became shorter and shorter, until one day in the cold wind, his The phone finally couldn't stand the cold, and turned off the phone without looking back.

Xiao Ming was very sad. He realized that he was going to change his mobile phone.

In order to get a better user experience, Xiao Ming gritted his teeth and bought an iphoneX. This phone has a big ringtone, a lot of power, and dual SIM and dual standby. Xiao Ming likes it very much, but he encountered a problem, that is He relied too much on the original iPhone 6 before, and they were deeply coupled together. If he wanted to change his mobile phone, he would have to use a knife to transform himself and replace the iphone 6 in all methods in his body with the iphone X.


long rebuilding process

After a long transformation process, Xiao Ming finally replaced all the iphone6 ​​in the code with iphoneX. Although it was very hard, Xiao Ming felt that he was happy.

于是小明开开心心地带着手机去上班了,并在回来的路上被小偷偷走了。为了应急,小明只好重新使用那部刚刚被遗弃的iphone6,但是一想到那漫长的改造过程,小明的心里就说不出的委屈,他觉得自己过于依赖手机了,为什么每次手机出什么问题他都要去改造他自己,这不仅仅是过度耦合,简直是本末倒置,他向天空大喊,我不要再控制我的手机了。

天空中的造物主,也就是作为程序员的我,听到了他的呐喊,我告诉他,你不用再控制你的手机了,交给我来管理,把控制权交给我。这就叫做控制反转


第三章:造物主的智慧


小明听到了我的话,他既高兴,又有一点害怕,他跪下来磕了几个头,虔诚地说到:“原来您就是传说中的造物主,巴格梅克上神。我听到您刚刚说了 控制反转 四个字,就是把手机的控制权从我的手里交给你,但这只是您的想法,是一种思想罢了,要用什么办法才能实现控制反转,又可以让我继续使用手机呢?”

“呵“,身为造物主的我在表现完不屑以后,扔下了四个大字,“依赖注入!”


接下来,伟大的我开始对小明进行惨无人道的改造,如下


class Ming extends Person
{
    private $_name;

    private $_age;

    private $_phone; //将手机作为自己的成员变量

    public function  __construct($phone)
    {
        $this->_name = '小明';
        $this->_age = 26;
        $this->_phone = $phone;
        echo "小明起床了 \n";
    }

    function read()
    {
        //……  省略若干代码
        $this->_phone->read($this->_name); //逛知乎
    }

    function  play()
    {
        //……  省略若干代码
        $this->_phone->play($this->_name);//玩农药

    }

    function  grab()
    {
        //……  省略若干代码
        $this->_phone->grab($this->_name);//抢红包

    }

}

接下来,我们来模拟运行小明的一天

$phone = new IphoneX(); //创建一个iphoneX的实例
if($phone->isBroken()){//如果iphone不可用,则使用旧版手机
    $phone = new Iphone6();
}
$ming = new Ming($phone);//小明不用关心是什么手机,他只要玩就行了。
$ming->read();
$ming->play();
$ming->grab();

我们先看一下iphoneX 是否可以使用,如果不可以使用,则直接换成iphone6,然后唤醒小明,并把手机塞到他的手里,换句话说,把他所依赖的手机直接注入到他的身上,他不需要关心自己拿的是什么手机,他只要直接使用就可以了。

这就是依赖注入


第四章:小明的感悟


小明的生活开始变得简单了起来,而他把省出来的时间都用来写笔记了,他在笔记本上这样写到


我曾经有很强的控制欲,过度依赖于我的手机,导致我和手机之间耦合程度太高,只要手机出现一点点问题,我都要改造我自己,这实在是既浪费时间又容易出问题。自从我把控制权交给了造物主,他每天在唤醒我以前,就已经替我选好了手机,我只要按照平时一样玩手机就可以了,根本不用关心是什么手机。即便手机出了问题,也可以由造物主直接搞定,不需要再改造我自己了,我现在买了七部手机,都交给了造物主,每天换一部,美滋滋!
我也从其中获得了这样的感悟: 如果一个类A 的功能实现需要借助于类B,那么就称类B是类A的 依赖,如果在类A的内部去实例化类B,那么两者之间会出现较高的 耦合,一旦类B出现了问题,类A也需要进行改造,如果这样的情况较多,每个类之间都有很多依赖,那么就会出现牵一发而动全身的情况, 程序会极难维护,并且很容易出现问题。要解决这个问题,就要把A类对B类的控制权抽离出来,交给一个第三方去做,把控制权反转给第三方,就称作 控制反转(IOC Inversion Of Control)控制反转是一种思想,是能够解决问题的一种可能的结果,而 依赖注入(Dependency Injection)就是其最典型的实现方法。由第三方( 我们称作IOC容器)来控制依赖,把他通过 构造函数、属性或者工厂模式等方法,注入到类A内,这样就极大程度的对类A和类B进行了 解耦


转自:https://zhuanlan.zhihu.com/p/33492169

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324701188&siteId=291194637