成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

PHP依賴注入和控制反轉(zhuǎn)的示例分析-創(chuàng)新互聯(lián)

這篇文章給大家分享的是有關(guān)PHP依賴注入和控制反轉(zhuǎn)的示例分析的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。

站在用戶的角度思考問題,與客戶深入溝通,找到勃利網(wǎng)站設(shè)計(jì)與勃利網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請域名、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋勃利地區(qū)。

首先先別追究這個(gè)設(shè)計(jì)模式的定義,否則你一定會被說的云里霧里,小編就是深受其害,百度了N多文章,都是從理論角度來描述,充斥著大量的生澀詞匯,要么就是java代碼描述的,也生澀。

不管怎么樣,總算弄清楚一些了,下面就以php的角度來描述一下依賴注入這個(gè)概念。

先假設(shè)我們這里有一個(gè)類,類里面需要用到數(shù)據(jù)庫連接,按照最最原始的辦法,我們可能是這樣寫這個(gè)類的:


class example {
  
  private $_db;
  function __construct(){
    include "./Lib/Db.php";
    $this->_db = new Db("localhost","root","123456","test");
  }
  function getList(){
    $this->_db->query("......");//這里具體sql語句就省略不寫了
  }
 }

過程:


在構(gòu)造函數(shù)里先將數(shù)據(jù)庫類文件include進(jìn)來;
然后又通過new Db并傳入數(shù)據(jù)庫連接信息實(shí)例化db類;
之后getList方法就可以通過$this->_db來調(diào)用數(shù)據(jù)庫類,實(shí)現(xiàn)數(shù)據(jù)庫操作。

看上去我們實(shí)現(xiàn)了想要的功能,但是這是一個(gè)噩夢的開始,以后example1,example2,example3....越來越多的類需要用到db組件,如果都這么寫的話,萬一有一天數(shù)據(jù)庫密碼改了或者db類發(fā)生變化了,豈不是要回頭修改所有類文件?
ok,為了解決這個(gè)問題,工廠模式出現(xiàn)了,我們創(chuàng)建了一個(gè)Factory方法,并通過Factory::getDb()方法來獲得db組件的實(shí)例:


class Factory {
  public static function getDb(){
    include "./Lib/Db.php";
    return new Db("localhost","root","123456","test");
  }
 }

sample類變成:


class example {
  
  private $_db;
  function __construct(){
    $this->_db = Factory::getDb();
  }
  function getList(){
    $this->_db->query("......");//這里具體sql語句就省略不寫了
  }
 }

這樣就完美了嗎?再次想想一下以后example1,example2,example3....所有的類,你都需要在構(gòu)造函數(shù)里通過Factory::getDb();獲的一個(gè)Db實(shí)例,實(shí)際上你由原來的直接與Db類的耦合變?yōu)榱撕虵actory工廠類的耦合,工廠類只是幫你把數(shù)據(jù)庫連接信息給包裝起來了,雖然當(dāng)數(shù)據(jù)庫信息發(fā)生變化時(shí)只要修改Factory::getDb()方法就可以了,但是突然有一天工廠方法需要改名,或者getDb方法需要改名,你又怎么辦?當(dāng)然這種需求其實(shí)還是很操蛋的,但有時(shí)候確實(shí)存在這種情況,一種解決方式是:

我們不從example類內(nèi)部實(shí)例化Db組件,我們依靠從外部的注入,什么意思呢?看下面的例子:


class example {
  private $_db;
  function getList(){
    $this->_db->query("......");//這里具體sql語句就省略不寫了
  }
  //從外部注入db連接
  function setDb($connection){
    $this->_db = $connection;
  }
 }
 //調(diào)用
$example = new example();
$example->setDb(Factory::getDb());//注入db連接
$example->getList();

這樣一來,example類完全與外部類解除耦合了,你可以看到Db類里面已經(jīng)沒有工廠方法或Db類的身影了。我們通過從外部調(diào)用example類的setDb方法,將連接實(shí)例直接注入進(jìn)去。這樣example完全不用關(guān)心db連接怎么生成的了。
這就叫依賴注入,實(shí)現(xiàn)不是在代碼內(nèi)部創(chuàng)建依賴關(guān)系,而是讓其作為一個(gè)參數(shù)傳遞,這使得我們的程序更容易維護(hù),降低程序代碼的耦合度,實(shí)現(xiàn)一種松耦合。

這還沒完,我們再假設(shè)example類里面除了db還要用到其他外部類,我們通過:


$example->setDb(Factory::getDb());//注入db連接
$example->setFile(Factory::getFile());//注入文件處理類
$example->setImage(Factory::getImage());//注入Image處理類
 ...

我們沒完沒了的寫這么多set?累不累?
ok,為了不用每次寫這么多行代碼,我們又去弄了一個(gè)工廠方法:


class Factory {
  public static function getExample(){
    $example = new example();
    $example->setDb(Factory::getDb());//注入db連接
    $example->setFile(Factory::getFile());//注入文件處理類
    $example->setImage(Factory::getImage());//注入Image處理類
    return $expample;
  }
 }

實(shí)例化example時(shí)變?yōu)椋?/p>

$example=Factory::getExample();
$example->getList();

似乎完美了,但是怎么感覺又回到了上面第一次用工廠方法時(shí)的場景?這確實(shí)不是一個(gè)好的解決方案,所以又提出了一個(gè)概念:容器,又叫做IoC容器、DI容器。

我們本來是通過setXXX方法注入各種類,代碼很長,方法很多,雖然可以通過一個(gè)工廠方法包裝,但是還不是那么爽,好吧,我們不用setXXX方法了,這樣也就不用工廠方法二次包裝了,那么我們還怎么實(shí)現(xiàn)依賴注入呢?
這里我們引入一個(gè)約定:在example類的構(gòu)造函數(shù)里傳入一個(gè)名為Di $di的參數(shù),如下:


class example {
  private $_di;
  function __construct(Di &$di){
    $this->_di = $di;
  }
  //通過di容器獲取db實(shí)例
  function getList(){
    $this->_di->get('db')->query("......");//這里具體sql語句就省略不寫了
  }
 }
$di = new Di();
$di->set("db",function(){
  return new Db("localhost","root","root","test"); 
 });
$example = new example($di);
$example->getList();

Di就是IoC容器,所謂容器就是存放我們可能會用到的各種類的實(shí)例,我們通過$di->set()設(shè)置一個(gè)名為db的實(shí)例,因?yàn)槭峭ㄟ^回調(diào)函數(shù)的方式傳入的,所以set的時(shí)候并不會立即實(shí)例化db類,而是當(dāng)$di->get('db')的時(shí)候才會實(shí)例化,同樣,在設(shè)計(jì)di類的時(shí)候還可以融入單例模式。


這樣我們只要在全局范圍內(nèi)申明一個(gè)Di類,將所有需要注入的類放到容器里,然后將容器作為構(gòu)造函數(shù)的參數(shù)傳入到example,即可在example類里面從容器中獲取實(shí)例。當(dāng)然也不一定是構(gòu)造函數(shù),你也可以用一個(gè) setDi(Di $di)的方法來傳入Di容器,總之約定是你制定的,你自己清楚就行。

這樣一來依賴注入以及關(guān)鍵的容器概念已經(jīng)介紹完畢,剩下的就是在實(shí)際中使用并理解它吧!

感謝各位的閱讀!關(guān)于“PHP依賴注入和控制反轉(zhuǎn)的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

文章名稱:PHP依賴注入和控制反轉(zhuǎn)的示例分析-創(chuàng)新互聯(lián)
分享網(wǎng)址:http://jinyejixie.com/article6/gpgig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、網(wǎng)站設(shè)計(jì)、外貿(mào)建站網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)公司手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
分宜县| 迭部县| 新和县| 青川县| 和静县| 夏津县| 赤城县| 芦山县| 依兰县| 双辽市| 林周县| 岳西县| 湘西| 清水县| 柘荣县| 周至县| 仙游县| 基隆市| 临清市| 祁东县| 米易县| 延庆县| 洪洞县| 丰镇市| 沂水县| 宿州市| 瑞昌市| 合肥市| 东乡县| 南乐县| 扶沟县| 蓬莱市| 靖江市| 台东县| 德昌县| 上思县| 新干县| 开鲁县| 西林县| 大同县| 仁化县|