提及 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