国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

淺談依賴注入與控制反轉(zhuǎn)

ThinkSNS / 1766人閱讀

摘要:但是,這是不是又有點(diǎn)熟悉的感覺和上面第一次用工廠類的時(shí)候一樣依賴于工廠。在框架開發(fā)中也會把反射與依賴注入控制反轉(zhuǎn)搭配使用,讓程序有強(qiáng)大的可控性和擴(kuò)展性。博客鏈接淺談依賴注入與控制反轉(zhuǎn)

前言:設(shè)計(jì)模式其實(shí)是一個(gè)很空洞的東西,設(shè)計(jì)模式有幾十種,有些人覺得工廠模式也單例模式已經(jīng)足夠解決大部分問題。而有些人覺得任何設(shè)計(jì)模式都會讓開發(fā)變得更“復(fù)雜”,更“低效”。所以千萬不要太過追求他的實(shí)際意義和作用,否則你已經(jīng)墜入云霧。但是不管怎么樣,實(shí)際工作中還是要對它們有所了解,下面從php的角度來講一下依賴注入、控制反轉(zhuǎn)、反射等概念。如有錯(cuò)誤之處,還望路過大神多加指點(diǎn)

首先設(shè)定場景,假如一個(gè)類需要數(shù)據(jù)庫連接,最簡單的做法可能是:

class example {
        private $_db;
        function __construct(){
            include "./Lib/Db.php";
            $this->_db = new Db("localhost","root","123456","test");
        }
        function getList(){
            $this->_db->query("......");
        }
    }

但事實(shí)上稍微有點(diǎn)經(jīng)驗(yàn)的同學(xué)都不會這樣寫,因?yàn)橐坏┰絹碓蕉嗟念愑玫絛b,而db一旦發(fā)生變化,那么豈不是要每個(gè)文件都修改一遍?這就是程序設(shè)計(jì)中的耦合問題。所有的類過度依賴 "./Lib/Db.php" 這個(gè)文件。OK,為了解決這個(gè)問題,工廠模式出現(xiàn)了,我們新建一個(gè) Factory 工廠類:

class Factory {
        public static function getDb(){
            include "./Lib/Db.php";
            return new Db("localhost","root","123456","test");
        }
    }
    class example {
        private $_db;
        function __construct(){
            $this->_db = Factory::getDb();
        }
        function getList(){
            $this->_db->query("......");
        }
    }

如果我們用到db模塊那么直接 Factory::getDb() 從工廠中取出來就是了,看似解決了問題。但事實(shí)是這樣嗎?不,這樣只不過是把程序與 db 模塊的耦合轉(zhuǎn)移到了 Factory ,一旦后期業(yè)務(wù)發(fā)生變動,F(xiàn)actory 發(fā)生變動,依舊要對每個(gè)文件改動。那如何解決呢?

我們可以不從example類內(nèi)部獲取db組件,我們從外部把db組件注入進(jìn)example類

class example {
        private $_db;
        function getList(){
            $this->_db->query("......");//執(zhí)行查詢
        }
        //從外部注入db連接
        function setDb($connection){
            $this->_db = $connection;
        }
    }
    $example = new example();
    $example->setDb(Factory::getDb());//注入db連接
    $example->getList();

這樣一來example就不用關(guān)心db組件怎么來的了,只用暴露一個(gè)注入方法即可。這就是 DI/依賴注入(Dependency Injection) , 不在內(nèi)部處理依賴關(guān)系,而是把依賴作為參數(shù)傳遞進(jìn)去,以降低程序的耦合性 。

然后我們的項(xiàng)目繼續(xù)進(jìn)行,用到了文件處理類,圖像處理類,我們可能會這樣寫

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

但是這樣似乎也不行啊,每次都要寫這么多代碼,于是我們又寫了一個(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;
        }
    }

example也不直接new 了。我們用 Factory::getExample()中獲取。但是,這是不是又有點(diǎn)熟悉的感覺?和上面第一次用工廠類的時(shí)候一樣依賴于工廠。于是又有了容器的概念。

class example {
    private $_di;
    function __construct(Di &$di){
        $this->_di = $di;
    }
    //通過di容器獲取db實(shí)例
    function getList(){
        $this->_di->get("db")->query("......");
    }
}
$di = new Di();
$di->set("db",function(){
   return new Db("localhost","root","root","test"); 
});
$example = new example($di);
$example->getList();

Di就是一個(gè)存放各種可擴(kuò)展的組件的容器,需要注入的時(shí)候調(diào)用$di->set()方法注入組件即可。程序中即可通過$di->get() 獲取組件。這樣被調(diào)用的組件(db)并不是由調(diào)用者(example)創(chuàng)建,而是由Di容器創(chuàng)建, 調(diào)用者失去控制權(quán),而容器得到控制權(quán),發(fā)生了控制權(quán)轉(zhuǎn)移 ,所以叫 做控制反轉(zhuǎn)(Inversion of Control)

但是這樣又有一些比較有強(qiáng)迫癥的同學(xué)發(fā)現(xiàn)了,每個(gè)類都要注入一遍容器是不是有些麻煩。沒錯(cuò),其實(shí)注入容器這個(gè)動作可以交給另外的程序處理,那就是反射。

_di->get("db")->query("......");
    }
}
//di容器
class Di{
    public $_container;
    public function get($cls){
        return $this->_container[$cls];
    }
    public function set($cls,$_instance){
        $this->_container[$cls]=$_instance;
    }
}
//db組件
class db{
    private static $_instance;//保存單例
    //單例方法
    public static function getInstance(){
        if(!(self::$_instance instanceof self)){
            self::$_instance = new self;
        }
        return self::$_instance;
    }
    //查詢方法
    public function query($sql){
        echo $sql;
    }
}

$di = new Di();//實(shí)例化容器
$di->set("db",db::getInstance());   //注入db實(shí)例


$reflector = new ReflectionClass("example");    //反射example,通過反射可以獲得該類的所有信息
$reflector->getDefaultProperties();             //example屬性
$reflector->getDocComment();               //注釋

$instance =$reflector->newInstanceArgs();       //相當(dāng)于實(shí)例化反射的example類
$instance->_di=$di;                             //注入di容器

$reflector->getmethod("getList")->invoke($instance);//調(diào)用example類方法

通過反射我們可以得到該類的全部信息,包括方法、方法名、屬性甚至注釋等等。通過反射我們可以方便的控制程序中使用的類,對他們進(jìn)行擴(kuò)展、修正、以及監(jiān)聽。通常反射在插件開發(fā)和框架開發(fā)中大量應(yīng)用。在框架開發(fā)中也會把反射與依賴注入、控制反轉(zhuǎn)搭配使用,讓程序有強(qiáng)大的可控性和擴(kuò)展性。

博客鏈接:淺談依賴注入與控制反轉(zhuǎn)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/23013.html

相關(guān)文章

  • PHPer、Laravel 面試可能會遇到的問題及答案

    摘要:如何實(shí)現(xiàn)持久化持久化,將在內(nèi)存中的的狀態(tài)保存到硬盤中,相當(dāng)于備份數(shù)據(jù)庫狀態(tài)。相當(dāng)于備份數(shù)據(jù)庫接收到的命令,所有被寫入的命令都是以的協(xié)議格式來保存的。 最近社區(qū)里面有一篇文章引起了最多程序猿的關(guān)注,Laravel、PHPer 面試可能會遇到的問題,看評論區(qū)不少小伙伴們被難倒,對于一些問題同樣難倒了我(其實(shí)有很多啦),趁著周末有空,又總結(jié)梳理了一遍,順便來答一波題。由于個(gè)人技術(shù)水平有限,答...

    fanux 評論0 收藏0
  • Spring理論基礎(chǔ)-控制反轉(zhuǎn)依賴注入

    摘要:控制反轉(zhuǎn)和依賴注入的關(guān)系也已經(jīng)清晰了,它們本質(zhì)上可以說是一樣的,只是具體的關(guān)注點(diǎn)不同。我的博客地址參考資料控制反轉(zhuǎn)和依賴注入的理解那些年搞不懂的高深術(shù)語依賴倒置控制反轉(zhuǎn)依賴注入面向接口編程控制反轉(zhuǎn)和依賴注入 序 第一次了解到控制反轉(zhuǎn)(Inversion of Control)這個(gè)概念,是在學(xué)習(xí)Spring框架的時(shí)候。IOC和AOP作為Spring的兩大特征,自然是要去好好學(xué)學(xué)的。而依賴...

    FullStackDeveloper 評論0 收藏0
  • Spring還可以這么學(xué)--IoC(控制反轉(zhuǎn)) / DI(依賴注入)理解

    摘要:對象之間耦合度過高的系統(tǒng),必然會出現(xiàn)牽一發(fā)而動全身的情形。控制被反轉(zhuǎn)之后,獲得依賴對象的過程由自身管理變?yōu)榱擞扇萜髦鲃幼⑷搿S谑牵o控制反轉(zhuǎn)取了一個(gè)更合適的名字叫做依賴注入。 Spring還可以這么學(xué)--IoC(控制反轉(zhuǎn)) / DI(依賴注入)理解 聲明:文章的前三部分參考博文:https://www.cnblogs.com/Nouno...這篇文章首發(fā)是在我的個(gè)人微信訂閱號每天學(xué)編...

    atinosun 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<