直接上例子:git
这不是依赖注入!程序员
//这不是依赖注入!!! class Bar { } class Foo { protected $bar; public function __construct() { $this->bar = new Bar(); } public function getBar() { return $this->bar; } } $foo = new Foo();
这就是依赖注入github
//这就是依赖注入。。。 class Bar { } class Foo { protected $bar; public function __construct(Bar $bar) { $this->bar = $bar; } public function getBar() { return $this->bar; } } $bar = new Bar(); $foo = new Foo($bar);
这也是依赖注入框架
//这也是依赖注入。。。 class Bar { } class Foo { protected $bar; public function __construct() { } public function setBar(Bar $bar) { $this->bar = $bar; } public function getBar() { return $this->bar; } } $bar = new Bar(); $foo = new Foo(); $foo->setBar($bar);
依赖注入就是new好了依赖的对象注入
进去,而不是在类中显式的new一个依赖的对象。其实,就是这么简单。。。this
虽然思想简单,可是在下降耦合度方面做用巨大。code
下面举个例子说明(just for demonstration):
好比咱们作了个小游戏,里面的男人能够亲本身的妻子。对象
abstract class Human { } class Woman extends Human { } class Man extends Human { protected $wife; public function __construct() { $this->wife = new Woman(); } public function kissWife() { echo "the man kissed his wife"; } } $man = new Man(); $man->kissWife();
玩的人越来也多,新需求随之而来。。。继承
产品经理(
腐腐
):妻子改为能够是男的吧,好多用户有这个需求,这样玩咱们游戏的确定更多。
程序员(猿猿
)内心:擦,Wife又能够是Man,又能够是Woman,这可咋整。接口
这个时候,依赖注入就能够闪亮登场了。游戏
abstract class Human { } class Woman extends Human { } class Man extends Human { protected $wife; public function setWife(Human $human) { $this->wife = $human; } public function kissWife() { echo "the man kissed his wife"; } } $man = new Man(); $man->setWife(new Woman()); $man->kissWife(); $anotherMan = new Man(); $anotherMan->setWife(new Man()); $anotherMan->kissWife();
这里咱们看到,依赖注入的能够是继承依赖类的任何类,因此如今Man的Wife既能够是Woman也能够是Man。
玩的人越来也多,新需求随之而来。。。
产品经理(
宅宅
):把妻子改为伴侣吧,伴侣里面除了Man和Woman再加个Cat,好多用户有这个需求,这样玩咱们游戏的确定更多。
程序员(猿猿
)内心:擦,又是Man又是Woman还有Cat,幸亏我会依赖注入。
abstract class Human { } interface canBePartner { } class Cat implements canBePartner { } class Woman extends Human implements canBePartner { } class Man extends Human implements canBePartner { protected $partner; public function setPartner(canBePartner $partner) { $this->partner = $partner; } public function kissPartner() { echo "the man kissed his partner"; } } $man = new Man(); $man->setPartner(new Woman()); $man->kissPartner(); $man2 = new Man(); $man2->setPartner(new Man()); $man2->kissPartner(); $man3 = new Man(); $man3->setPartner(new Cat()); $man3->kissPartner();
这里咱们看到,依赖注入不但能够是继承依赖类的全部子类,也能够是实现依赖接口的全部类。
因此若是咱们在伴侣中再加入一个Dog,只须要让它实现canBePartner接口就能够了:
class Dog implements canBePartner { } $man = new Man(); $man->setPartner(new Dog());
依赖注入虽然下降了耦合度,可是也有缺点,就是须要咱们本身管理注入的对象。
因此,在实际应用中,咱们一般须要实现一个容器去管理和实现依赖对象的注入。
实际上,PHP的经常使用Web框架中都是这么作的。
博客地址:http://haitian299.github.io/2016/05/17/Dependency-injection/