上一篇:Git系列之git blame:找出真凶(2019-10-26 02:38:37)

什么是依赖注入和控制反转

2019年10月28日 21:48

这个东西其实很好理解,但是却不知道为何工作好多年之前却一直一知半解,而且时间一长就会忘。

如今反思,觉得主要还是因为对于依赖注入和控制反转这个奇怪的叫法,根本就没理解到位。


后来看到一些好文章,针对这两个词汇字字分析到位,仿佛顿时云开月明。

检验一个人是否真的弄懂了某个知识点的最好验证方法就是:说给别人听或者写给别人看。我今天于是选择了写写,来检验检验自己,同时也分享分享给大家。


什么是依赖?

所谓依赖(Dependency),就是依靠、离不开的意思,换言之也就是需要。

例如小汽车需要门,还需要轮胎,我们从设计程序的角度来理解,就可以理解成小汽车依赖门和轮胎。于是关于类的大概设计就有了如下所示:

class Car{
	private $door;
	private $wheel;
	function __construct(){
		$this->door 	= new Door;
		$this->wheel 	= new Wheel;
	}

	public function run(){
		$this->door->close();
		$this->wheel->makeFull();
		echo "All are ready,car begins to run...";
	}
}


class Door{
	//关车门
	public function close(){
		echo "Closing the door...<br>";
	}
}

class Wheel{
	//给轮胎打满气
	public function makeFull(){
		echo "Make all tyre full...<br>";
	}
}

$car = new Car();
$car->run();

从Car类的构造函数中可以看到,door和wheel两个属性被赋值了各自类的实例。从逻辑上来说,实例化Car类,必须先实例化Door和Wheel,也就是说Car类需要Door类和Wheel类,即Car类是依赖Door和Wheel类的。


本文是翟码农个人博客蓝翟红尘里的PHP专题下的的文章,转载请注明出处:http://www.zhai14.com/blog/6801e8176b4df0db4e4069fbead45cc6.html


什么是注入?

我们可以把它想象成打针(injection)这一行为:把药物注射进我们身体。对照上面Car类的设计,Car类就相当于我们的身体,而药物则相当于外来物,是要被注射进我们身体才会溶入我们身体的。根据这个思想,上面Car类的设计就变成如下:

class Car{
	private $door;
	private $wheel;
	function __construct(Door $door, Wheel $wheel){
		$this->door 	= new Door;
		$this->wheel 	= new Wheel;
	}

	public function run(){
		$this->door->close();
		$this->wheel->makeFull();
		echo "All are ready,car begins to run...";
	}
}


class Door{
	//关车门
	public function close(){
		echo "Closing the door...<br>";
	}
}

class Wheel{
	//给轮胎打满气
	public function makeFull(){
		echo "Make all tyre full...<br>";
	}
}
//在外部实例化Door和Wheel类,通过作为构造函数的参数注入到Car类
$car = new Car(new Door, new Wheel);
$car->run();

在讲解依赖的部分,我们可以看到Door类和Wheel类的实例化都是在Car类构造函数中实例化的,也就是说它们相对于Car并不算外来物,而是一开始就已融进Car类的血肉里了。

但看我们上面的代码,Door和Wheel类是在外部程序实例化的,然后再作为构造函数的参数传进Car类里的,这样就叫做注入。


什么是控制反转?

控制反转,英文Inversion Of Control,缩写Ioc。

为了方便理解,我们将上面小程序划分为两个部分:Car类内部和Car类外部。

为了方便说明,上面讲解依赖和注入部分的程序,我们暂称之为A和B。


在A里,Door类和Wheel类是在Car类的构造函数里实例化的,构造函数是在Car类内部的,也就是说,此时Door类和Wheel类的实例化是由Car类内部控制的。

在B里,Door类和Wheel类则是在Car类外部实例化,然后通过Car类构造函数注入进去的,也就是说,此时Door类和Wheel类的实例化是由Car类外部控制的。

由此对比,我想你一眼就可以看出控制反转的含义了吧。


判断你们是否看懂,问你们一个问题:那为啥不叫控制变换或控制变更啥的呢?

主要还是在于上面我说的对程序空间理解的划分:内部和外部。内和外是反义词,且从A到B控制权是由内转变为由外的,所以叫反转才更为贴切。


再梳理一下依赖注入和反转控制的概念,我们就会意识到依赖注入是对类设计的一种描述,而控制反转则是对注入这一行为所引起的现象的描述。

简言之,注入是行为,控制反转是效果。

总结:注入是行为,控制反转是效果


  • 2019年10月26日 22:39文章创建
  • 2019年10月28日 21:48文章发布
上一篇:Git系列之git blame:找出真凶(2019-10-26 02:38:37)
我要评论
«-必填,限2-20个字符,中文/字母/字母数字组合
«-评论后,邮箱会收到激活链接,未激活邮箱的留言,将无法显示
评论列表
暂无评论,期待你的评论哦!
回到顶部