何为依赖注入(DEPENDENCY INJECTION)?
平常在写代码的时候,经常会在一个类中写出这样的一段代码(以 PHP 代码展示):
<?php
class Apple
{
protected $color;
public function __construct()
{
$color = new Red();
$this->color = $color;
}
}
在这段代码中,创建了一个 “苹果” 实例的同时,也创建了一个 “红色” 实例,这时,“苹果” 与 “红色” 之间,就产生了一个依赖。
依赖,就是我不能失去你,不然就不能存活了
如果需求变更,需要给 “苹果“ 增加一个青色的属性,在这一段代码中,似乎并没有什么大影响,我们只需要这样:
<?php
class Apple
{
protected $color;
public function __construct($color)
{
switch ($color){
case "red":
$color = new Red();
break;
case "green":
$color = new Green();
break;
}
$this->color = $color;
}
}
给 ”苹果“ 加多一个属性就完成了,是不是看起来还是挺简单的。但是,当你需要添加一个其他属性的时候,例如:黄苹果。这个时候我们就需要重新编写这个 ”苹果“ 的类了,体验还是没有好转。
那么有什么解决的方法吗?既然在 ”苹果“ 内部实现他的色彩属性不是一个好的做法,何不把 ”苹果“ 色彩的构建放置到外部来实现呢?这就是我们标题所提到的 ”依赖注入“ 了。
依赖注入(dependency injection)
我们看下面一段代码
<?php
interface Color
{
//在这里我们定义好一些接口
}
class Red implements Color
{
//Red集成Color接口
}
class Green implements Color
{
//Green集成Color接口
}
class Apple
{
protected $color;
public function __construct(Color $color)
{
$this->color = $color;
}
}
现在,我们可以从外面传入一个实例化的类到 ”苹果“ 类中了,为了防止传入不相干的实例,我们在 ”苹果“ 类的 __construct 传入的实例进行了限制,传入实例必须实现 ”Color“ 接口。否则就会产生错误。
现在,我们只需要像下面这样就能创造出想要的苹果了:
$color = new Red();
$apple = new Apple($color);
这就是一个典型的依赖注入了。