最近在看一些文章的時候,無心間看到別人分享的關於依賴注入和控制反轉的最通俗的解釋,在此記一筆php
首先要知道,IOC不是一種技術,只是一種編程思想,它能指導咱們如何設計出鬆耦合、更優良的程序。咱們日常開發一個應用程序,都是由咱們在類內部主動建立依賴對象,從而致使類與類之間高耦合,對後期的擴展性和調試維護都是多少帶來不便,而提出了IOC容器思想後,咱們在應用層開發時,所須要依賴的類的建立和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,因此對象與對象之間是 鬆散耦合,這樣也方便測試,利於功能複用,更重要的是使得程序的整個體系結構變得很是靈活。數據庫
-----編程
網上有一個通俗的解釋是這樣的,很是便於記憶:app
1.1 首先想說說IOC(Inversion of Control,控制反轉),這是什麼意思呢,舉個簡單的例子,咱們是如何找女友的?常見的狀況是,咱們處處去看哪裏有長得漂亮身材又好的×××姐,而後打聽她們的興趣愛好、qq號、電話號、ip號、iq號………,想辦法認識她們,投其所好送其所要,而後嘿嘿……這個過程是複雜深奧的,咱們必須本身設計和麪對每一個環節。傳統的程序開發也是如此,在一個對象中,若是要使用另外的對象,就必須獲得它(本身new一個,或者從JNDI中查詢一個),使用完以後還要將對象銷燬(好比Connection等),對象始終會和其餘的接口或類藕合起來。ide
那麼IOC是如何作的呢?有點像經過婚介找女友,在我和女友之間引入了一個第三者:婚姻介紹所。婚介管理了不少男男女女的資料,我能夠向婚介提出一個列表,告訴它我想找個什麼樣的女友,好比長得像李嘉欣,身材像林熙雷,唱歌像周杰倫,速度像卡洛斯,技術像齊達內之類的,而後婚介就會按照咱們的要求,提供一個mm,咱們只須要去和她談戀愛、結婚就好了。簡單明瞭,若是婚介給咱們的人選不符合要求,咱們就會拋出異常。整個過程再也不由我本身控制,而是有婚介這樣一個相似容器的機構來控制。而對於IOC的概念,就是全部的類的建立、銷燬都由 IOC容器來控制,也就是說控制對象生存週期的再也不是引用它的對象,而是IOC容器。對於某個具體的對象而言,之前是它控制其餘對象,如今是全部對象都被IOC容器控制,因此這叫控制反轉。svg
2.二、DI(依賴注入)測試
IOC的一個重點是在系統運行中,動態的向某個對象提供它所須要的其餘對象。這一點是經過DI(Dependency Injection,依賴注入)來實現的。好比對象A須要操做數據庫,之前咱們老是要在A中本身編寫代碼來得到一個Connection對象,有了 IOC容器咱們就只須要告訴容器,A中須要一個Connection,至於這個Connection怎麼構造,什麼時候構造,A不須要知道。在系統運行時,容器會在適當的時候製造一個Connection,而後像打針同樣,注射到A當中,這樣就完成了對各個對象之間關係的控制。A須要依賴 Connection才能正常運行,而這個Connection是由容器注入到A中的,依賴注入的名字就這麼來的。那麼DI是如何實現的呢? Java 、php等都引入了一個重要機制,即反射(reflection),它容許程序在運行的時候動態的生成對象、執行對象的方法、改變對象的屬性this
因此控制反轉IOC(Inversion of Control)是說建立對象的控制權進行轉移,之前建立對象的主動權和建立時機是由本身把控的,而如今這種權力轉移到第三方,好比轉移交給了IOC容器,它就是一個專門用來建立對象的工廠,你要什麼對象,它就給你什麼對象,有了 IOC容器,依賴關係就變了,原先的依賴關係就沒了,它們都依賴IOC容器了,經過IOC容器來創建它們之間的關係。url
總結:控制的什麼被反轉了?就是:得到依賴對象的方式反轉了。
spa
下面列舉一個簡單的IOC/DI示例,進一步掌握這個概念究竟是個什麼鬼!
代碼示意:
代碼示意:
<?php /** * 沒有IoC/DI的時候,常規的A類使用C類的示例 */ /** * Class C */ class C { public function say() { echo 'hello'; } } /** * Class A */ class A { private $c; public function __construct() { $this->c = new C(); // 實例化建立C類 } public function sayC() { echo $this->c->say(); // 調用C類中的方法 } } $a = new a(); $a->sayC();
當有了IoC/DI的容器後,A類再也不主動去建立C了,以下圖所示:
而是被動等待,等待IoC/DI的容器獲取一個C的實例,而後反向的注入到A類中,以下圖所示:
代碼示意:
<?php/** * 當有了IoC/DI的容器後,a類依賴c實例注入的示例 *//** * Class c */class c{ public function say() { echo 'hello'; } }/** * Class a */class a{ private $c; public function setC(C $c) { $this->c = $c; // 實例化建立C類 } public function sayC() { echo $this->c->say(); // 調用C類中的方法 } } $c = new C(); $a = new a(); $a->setC($c); $a->sayC();