在说依赖注入之前,我们想来说说什么是依赖。
这里的依赖并不是互相依赖,而是单方面的依赖,生活中有很多这样的例子:鱼对水的依赖、汽车对零件的依赖、手机对于电的依赖。
这里用汽车与车轮来举个例子。
现在我们有汽车类和基本车轮类:
<?php
class Car
{
protected $wheel;
public function __construct()
{
$this->wheel = new BaseWheel();
}
}
class BaseWheeel
{ ... }
所以我们现在造汽车的方式为:
$car = new Car();
可以看到上面一行代码就可以解决了,很方便,但是如果需求变了,轮胎换成了 FastWheel()
,那我们就要去 Car
里修改。
<?php
class Car
{
protected $wheel;
public function __construct()
{
// $this->wheel = new Wheel(); 改需求了
$this->wheel = new FastWheel();
}
}
现在虽然我们创造一个 Car
类只需要一行命令,但是如果轮胎的需求变了,我们岂不是每次都要修改 Car
的代码。这就是我们说的强耦合。那有没有办法降低耦合呢?就是 依赖注入 。依赖注入就是通过注入的方式来实现解耦。
如果我们先定义一个车轮接口,其他新增的需求通过实现车轮接口来解决。
<?php
interface Wheeel
{ ... }
class BaseWheel implements Whell
{ ... }
class FastWhell implements Whell
{ ... }
紧接着,我们 Car
也要跟着改变:
<?php
class Car
{
protected $wheel;
public function __construct(Wheel $wheel)
{
$this->wheel = $wheel;
}
}
现在我们创建一个辆车,就成了这样:
$basewheel = new BaseWheel();
$fastwheel = new FastWheel();
$basecar = new Car($basewheel);
$fastcar = new Car($fastwheel);
如果接下来车轮需求进行变更,我们只需要让其实现 Wheel
接口即可,而不用懂 Car
中的代码,实现了程序设计中的 高内聚低耦合 。
上述只是依赖注入的一种实现:以构造器注入。
还有:
- 以设值方法注入
- 以类成员变量方式注入
- 等
但是这样我们还不是很满意,服务容器( ICO 容器)就是让这一切自动化的过程。
依赖注入是控制反转的一种是实现方法,而控制反转又是依赖反转原则的一种思路,而这里的服务容器就是控制反转的一种容器。