推荐一篇介绍依赖注入的基础文章依赖注入基础讲解

    说白了, 依赖注入就是不直接在使用类的内部创建对象, 而是将对象作为调用类的一个属性, 这样能够降低类与类之间的耦合, 使程序更加的灵活可变。还是举个简单的例子吧。
    先来定义三个文件分别是 IGun.php , PistolGun.php, Soldier.php

    1. //IGun.php
    2. interface IGun
    3. {
    4. public function getName();
    5. public function shoot();
    6. }
    7. // PistoGun.php
    8. class PistolGun implements IGun
    9. {
    10. private $name = 'Pisto';
    11. public function getName()
    12. {
    13. return $this->name;
    14. }
    15. public function shoot()
    16. {
    17. echo 'Pisto shoot' . PHP_EOL;
    18. }
    19. }
    20. // Soldier.php
    21. // 士兵使用枪射杀敌人
    22. class Soldier
    23. {
    24. private $gun;
    25. public function __construct()
    26. {
    27. $this->gun = new PistolGun();
    28. }
    29. public function shoot()
    30. {
    31. echo 'soldier use ' . $this->gun->shoot();
    32. }
    33. public function getGunName()
    34. {
    35. echo $this->gun->getName();
    36. }
    37. }

    这样的代码应该是很容易写出来的, 现在问题来了, 为了增强士兵的杀敌能力和自保能力, 政府决定每人一把加特林。为了更改我们必须修改这个类,但是在下一次战争中可能是游击战, 为了灵活又要使用手枪了, 这种事情虽然不可能出现, 但在编程世界里应该随时都可能发生, 为了能够使这个类更加灵活, 于是就引入了依赖注入一说, 现在我们增加一个类, 并且使用依赖注入的写法。

    1. // Gatling.php
    2. class Gatling implements IGun
    3. {
    4. private $name = 'Gatling';
    5. public function shoot()
    6. {
    7. echo $this->name . 'shoot' . PHP_EOL;
    8. }
    9. public function getName()
    10. {
    11. return $this->name;
    12. }
    13. }

    // 依赖注入的写法

    1. // Soldier.php
    2. // 士兵使用枪射杀敌人
    3. class Soldier
    4. {
    5. private $gun;
    6. public function __construct(IGun $_gun)
    7. {
    8. $this->gun = $_gun;
    9. }
    10. public function shoot()
    11. {
    12. echo 'soldier use ' . $this->gun->shoot();
    13. }
    14. public function getGunName()
    15. {
    16. echo $this->gun->getName();
    17. }
    18. }
    19. (new Soldier(new Gatling())) -> shoot(); //使用加特林的士兵射击
    20. (new Soldier(new PistolGun())) -> shoot(); // 使用手枪的士兵射击

    依赖注入就是通过注入不同的对象来实现灵活性, 但是我们需要使用约束(接口和抽象)以保证程序的正常运行(总不能随便一个类我就用吧)
    除了通过构造函数,也可以使用setter方法注入依赖。

    1. // 在Solder中
    2. public function setGun(IGun $_gun) {
    3. $this->gun = $_gun;
    4. }

    如果使用setter方法, 或许需要加点检测, 以防止没有调用setter方法, 就开始上阵杀敌。试想下, 你上战场了, 但是忘了带枪了(这样我想起了一部电影—血战钢锯岭, 但我觉得不是每个人都有那样的运气。)这基本和故意送人头没区别了, 是要被举报的。