在说依赖注入之前,我们想来说说什么是依赖。
    这里的依赖并不是互相依赖,而是单方面的依赖,生活中有很多这样的例子:鱼对水的依赖、汽车对零件的依赖、手机对于电的依赖。
    这里用汽车与车轮来举个例子。
    现在我们有汽车类和基本车轮类:

    1. <?php
    2. class Car
    3. {
    4. protected $wheel;
    5. public function __construct()
    6. {
    7. $this->wheel = new BaseWheel();
    8. }
    9. }
    1. class BaseWheeel
    2. { ... }

    所以我们现在造汽车的方式为:

    1. $car = new Car();

    可以看到上面一行代码就可以解决了,很方便,但是如果需求变了,轮胎换成了 FastWheel() ,那我们就要去 Car 里修改。

    1. <?php
    2. class Car
    3. {
    4. protected $wheel;
    5. public function __construct()
    6. {
    7. // $this->wheel = new Wheel(); 改需求了
    8. $this->wheel = new FastWheel();
    9. }
    10. }

    现在虽然我们创造一个 Car 类只需要一行命令,但是如果轮胎的需求变了,我们岂不是每次都要修改 Car 的代码。这就是我们说的强耦合。那有没有办法降低耦合呢?就是 依赖注入 。依赖注入就是通过注入的方式来实现解耦。
    如果我们先定义一个车轮接口,其他新增的需求通过实现车轮接口来解决。

    1. <?php
    2. interface Wheeel
    3. { ... }
    4. class BaseWheel implements Whell
    5. { ... }
    6. class FastWhell implements Whell
    7. { ... }

    紧接着,我们 Car 也要跟着改变:

    1. <?php
    2. class Car
    3. {
    4. protected $wheel;
    5. public function __construct(Wheel $wheel)
    6. {
    7. $this->wheel = $wheel;
    8. }
    9. }

    现在我们创建一个辆车,就成了这样:

    1. $basewheel = new BaseWheel();
    2. $fastwheel = new FastWheel();
    3. $basecar = new Car($basewheel);
    4. $fastcar = new Car($fastwheel);

    如果接下来车轮需求进行变更,我们只需要让其实现 Wheel 接口即可,而不用懂 Car 中的代码,实现了程序设计中的 高内聚低耦合 。
    上述只是依赖注入的一种实现:以构造器注入。
    还有:

    • 以设值方法注入
    • 以类成员变量方式注入

    但是这样我们还不是很满意,服务容器( ICO 容器)就是让这一切自动化的过程。
    依赖注入是控制反转的一种是实现方法,而控制反转又是依赖反转原则的一种思路,而这里的服务容器就是控制反转的一种容器。