推荐一篇介绍依赖注入的基础文章依赖注入基础讲解
说白了, 依赖注入就是不直接在使用类的内部创建对象, 而是将对象作为调用类的一个属性, 这样能够降低类与类之间的耦合, 使程序更加的灵活可变。还是举个简单的例子吧。
先来定义三个文件分别是 IGun.php , PistolGun.php, Soldier.php
//IGun.php
interface IGun
{
public function getName();
public function shoot();
}
// PistoGun.php
class PistolGun implements IGun
{
private $name = 'Pisto';
public function getName()
{
return $this->name;
}
public function shoot()
{
echo 'Pisto shoot' . PHP_EOL;
}
}
// Soldier.php
// 士兵使用枪射杀敌人
class Soldier
{
private $gun;
public function __construct()
{
$this->gun = new PistolGun();
}
public function shoot()
{
echo 'soldier use ' . $this->gun->shoot();
}
public function getGunName()
{
echo $this->gun->getName();
}
}
这样的代码应该是很容易写出来的, 现在问题来了, 为了增强士兵的杀敌能力和自保能力, 政府决定每人一把加特林。为了更改我们必须修改这个类,但是在下一次战争中可能是游击战, 为了灵活又要使用手枪了, 这种事情虽然不可能出现, 但在编程世界里应该随时都可能发生, 为了能够使这个类更加灵活, 于是就引入了依赖注入一说, 现在我们增加一个类, 并且使用依赖注入的写法。
// Gatling.php
class Gatling implements IGun
{
private $name = 'Gatling';
public function shoot()
{
echo $this->name . 'shoot' . PHP_EOL;
}
public function getName()
{
return $this->name;
}
}
// 依赖注入的写法
// Soldier.php
// 士兵使用枪射杀敌人
class Soldier
{
private $gun;
public function __construct(IGun $_gun)
{
$this->gun = $_gun;
}
public function shoot()
{
echo 'soldier use ' . $this->gun->shoot();
}
public function getGunName()
{
echo $this->gun->getName();
}
}
(new Soldier(new Gatling())) -> shoot(); //使用加特林的士兵射击
(new Soldier(new PistolGun())) -> shoot(); // 使用手枪的士兵射击
依赖注入就是通过注入不同的对象来实现灵活性, 但是我们需要使用约束(接口和抽象)以保证程序的正常运行(总不能随便一个类我就用吧)
除了通过构造函数,也可以使用setter方法注入依赖。
// 在Solder中
public function setGun(IGun $_gun) {
$this->gun = $_gun;
}
如果使用setter方法, 或许需要加点检测, 以防止没有调用setter方法, 就开始上阵杀敌。试想下, 你上战场了, 但是忘了带枪了(这样我想起了一部电影–血战钢锯岭, 但我觉得不是每个人都有那样的运气。)这基本和故意送人头没区别了, 是要被举报的。