提及 IoC,实际上是 Inversion of Control 的缩写,翻译成中文叫控制反转,不得不说这个名字起得让人丈二和尚摸不着头脑,实际上简而言之它的意思是说对象之间不免会有各类各样的依赖关系,若是咱们的代码直接依赖于具体的实现,那么就是一种强耦合,从而下降了系统的灵活性,为了解耦,咱们的代码应该依赖接口,至于具体的实现,则经过第三方注入进去,这里的第三方一般就是咱们常说的容器。由于在这个过程当中,具体实现的控制权从咱们的代码转移到了容器,因此称之为控制反转。php
Ioc有两种不一样的实现方式,分别是:Dependency Injection 和 Service Locator。如今不少 PHP 框架都实现了容器,好比 Phalcon,Yii,Laravel 等。框架
至于 Dependency Injection 和 Service Locator 的区别,与其说一套云山雾绕的概念,不能给出几个鲜活的例子来得天然。ui
若是没有容器,那么 Dependency Injection 看起来就像:this
class Foo { protected $_bar; protected $_baz; public function __construct(Bar $bar, Baz $baz) { $this->_bar = $bar; $this->_baz = $baz; } } // In our test, using PHPUnit's built-in mock support $bar = $this->getMock('Bar'); $baz = $this->getMock('Baz'); $testFoo = new Foo($bar, $baz);
若是有容器,那么 Dependency Injection 看起来就像:翻译
// In our test, using PHPUnit's built-in mock support $container = $this->getMock('Container'); $container['bar'] = $this->getMock('Bar'); $container['baz'] = $this->getMock('Baz'); $testFoo = new Foo($container['bar'], $container['baz']);
经过引入容器,咱们能够把全部的依赖都集中管理,这样有不少好处,好比说咱们能够很方便的替换某种依赖的实现方式,从而提高系统的灵活性。
看看下面这个实现怎么样?是否是 Dependency Injection?code
class Foo { protected $_bar; protected $_baz; public function __construct(Container $container) { $this->_bar = $container['bar']; $this->_baz = $container['baz']; } } // In our test, using PHPUnit's built-in mock support $container = $this->getMock('Container'); $container['bar'] = $this->getMock('Bar'); $container['baz'] = $this->getMock('Bar'); $testFoo = new Foo($container);
虽然从表面上看它也使用了容器,并不依赖具体的实现,但你若是仔细看就会发现,它依赖了容器自己,实际上这不是 Dependency Injection,而是 Service Locator。对象
因而乎判断 Dependency Injection 和 Service Locator 区别的关键是在哪使用容器:接口
若是在非工厂对象的外面使用容器,那么就属于 Dependency Injection。get
若是在非工厂对象的内部使用容器,那么就属于 Service Locator。it