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

資訊專欄INFORMATION COLUMN

深入理解控制反轉(zhuǎn)(IoC)和依賴注入(DI)

HollisChuang / 1601人閱讀

摘要:本文一大半內(nèi)容都是通過舉例來讓讀者去理解什么是控制反轉(zhuǎn)和依賴注入,通過理解這些概念,來更加深入。這種由外部負(fù)責(zé)其依賴需求的行為,我們可以稱其為控制反轉(zhuǎn)。工廠模式,依賴轉(zhuǎn)移當(dāng)然,實(shí)現(xiàn)控制反轉(zhuǎn)的方法有幾種。

容器,字面上理解就是裝東西的東西。常見的變量、對(duì)象屬性等都可以算是容器。一個(gè)容器能夠裝什么,全部取決于你對(duì)該容器的定義。當(dāng)然,有這樣一種容器,它存放的不是文本、數(shù)值,而是對(duì)象、對(duì)象的描述(類、接口)或者是提供對(duì)象的回調(diào),通過這種容器,我們得以實(shí)現(xiàn)許多高級(jí)的功能,其中最常提到的,就是 “解耦” 、“依賴注入(DI)”。本文就從這里開始。
IoC 容器, laravel 的核心

Laravel 的核心就是一個(gè) IoC 容器,根據(jù)文檔,稱其為“服務(wù)容器”,顧名思義,該容器提供了整個(gè)框架中需要的一系列服務(wù)。作為初學(xué)者,很多人會(huì)在這一個(gè)概念上犯難,因此,我打算從一些基礎(chǔ)的內(nèi)容開始講解,通過理解面向?qū)ο箝_發(fā)中依賴的產(chǎn)生和解決方法,來逐漸揭開“依賴注入”的面紗,逐漸理解這一神奇的設(shè)計(jì)理念。

本文一大半內(nèi)容都是通過舉例來讓讀者去理解什么是 IoC(控制反轉(zhuǎn)) 和 DI(依賴注入),通過理解這些概念,來更加深入。更多關(guān)于 laravel 服務(wù)容器的用法建議閱讀文檔即可。

IoC 容器誕生的故事

講解 IoC 容器有很多的文章,我之前也寫過。但現(xiàn)在我打算利用當(dāng)下的靈感重新來過,那么開始吧。

超人和超能力,依賴的產(chǎn)生!

面向?qū)ο缶幊蹋幸韵聨讟訓(xùn)|西無時(shí)不刻的接觸:接口還有對(duì)象。這其中,接口是類的原型,一個(gè)類必須要遵守其實(shí)現(xiàn)的接口;對(duì)象則是一個(gè)類實(shí)例化后的產(chǎn)物,我們稱其為一個(gè)實(shí)例。當(dāng)然這樣說肯定不利于理解,我們就實(shí)際的寫點(diǎn)中看不中用的代碼輔助學(xué)習(xí)。

怪物橫行的世界,總歸需要點(diǎn)超級(jí)人物來擺平。

我們把一個(gè)“超人”作為一個(gè)類,

class Superman {}

我們可以想象,一個(gè)超人誕生的時(shí)候肯定擁有至少一個(gè)超能力,這個(gè)超能力也可以抽象為一個(gè)對(duì)象,為這個(gè)對(duì)象定義一個(gè)描述他的類吧。一個(gè)超能力肯定有多種屬性、(操作)方法,這個(gè)盡情的想象,但是目前我們先大致定義一個(gè)只有屬性的“超能力”,至于能干啥,我們以后再豐富:

class Power {
    /**
     * 能力值
     */
    protected $ability;

    /**
     * 能力范圍或距離
     */
    protected $range;

    public function __construct($ability, $range)
    {
        $this->ability = $ability;
        $this->range = $range;
    }
}

這時(shí)候我們回過頭,修改一下之前的“超人”類,讓一個(gè)“超人”創(chuàng)建的時(shí)候被賦予一個(gè)超能力:

class Superman
{
    protected $power;

    public function __construct()
    {
        $this->power = new Power(999, 100);
    }
}

這樣的話,當(dāng)我們創(chuàng)建一個(gè)“超人”實(shí)例的時(shí)候,同時(shí)也創(chuàng)建了一個(gè)“超能力”的實(shí)例,但是,我們看到了一點(diǎn),“超人”和“超能力”之間不可避免的產(chǎn)生了一個(gè)依賴。

所謂“依賴”,就是 “我若依賴你,我就不能離開你”。

在一個(gè)貫徹面向?qū)ο缶幊痰捻?xiàng)目中,這樣的依賴隨處可見。少量的依賴并不會(huì)有太過直觀的影響,我們隨著這個(gè)例子逐漸鋪開,讓大家慢慢意識(shí)到,當(dāng)依賴達(dá)到一個(gè)量級(jí)時(shí),是怎樣一番噩夢般的體驗(yàn)。當(dāng)然,我也會(huì)自然而然的講述如何解決問題。

一堆亂麻 —— 可怕的依賴

之前的例子中,超能力類實(shí)例化后是一個(gè)具體的超能力,但是我們知道,超人的超能力是多元化的,每種超能力的方法、屬性都有不小的差異,沒法通過一種類描述完全。我們現(xiàn)在進(jìn)行修改,我們假設(shè)超人可以有以下多種超能力:

飛行,屬性有:飛行速度、持續(xù)飛行時(shí)間

蠻力,屬性有:力量值

能量彈,屬性有:傷害值、射擊距離、同時(shí)射擊個(gè)數(shù)

我們創(chuàng)建了如下類:

class Flight
{
    protected $speed;
    protected $holdtime;
    public function __construct($speed, $holdtime) {}
}

class Force
{
    protected $force;
    public function __construct($force) {}
}

class Shot
{
    protected $atk;
    protected $range;
    protected $limit;
    public function __construct($atk, $range, $limit) {}
}

*為了省事兒我沒有詳細(xì)寫出 __construct() 這個(gè)構(gòu)造函數(shù)的全部,只寫了需要傳遞的參數(shù)。

好了,這下我們的超人有點(diǎn)“忙”了。在超人初始化的時(shí)候,我們會(huì)根據(jù)需要來實(shí)例化其擁有的超能力嗎,大致如下:

class Superman
{
    protected $power;

    public function __construct()
    {
        $this->power = new Fight(9, 100);
        // $this->power = new Force(45);
        // $this->power = new Shot(99, 50, 2);
        /*
        $this->power = array(
            new Force(45),
            new Shot(99, 50, 2)
        );
        */
    }
}

我們需要自己手動(dòng)的在構(gòu)造函數(shù)內(nèi)(或者其他方法里)實(shí)例化一系列需要的類,這樣并不好。可以想象,假如需求變更(不同的怪物橫行地球),需要更多的有針對(duì)性的 新的 超能力,或者需要 變更 超能力的方法,我們必須 重新改造 超人。換句話說就是,改變超能力的同時(shí),我還得重新制造個(gè)超人。效率太低了!新超人還沒創(chuàng)造完成世界早已被毀滅。

這時(shí),靈機(jī)一動(dòng)的人想到:為什么不可以這樣呢?超人的能力可以被隨時(shí)更換,只需要添加或者更新一個(gè)芯片或者其他裝置啥的(想到鋼鐵俠沒)。這樣的話就不要整個(gè)重新來過了。

對(duì),就是這樣的。

我們不應(yīng)該手動(dòng)在 “超人” 類中固化了他的 “超能力” 初始化的行為,而轉(zhuǎn)由外部負(fù)責(zé),由外部創(chuàng)造超能力模組、裝置或者芯片等(我們后面統(tǒng)一稱為 “模組”),植入超人體內(nèi)的某一個(gè)接口,這個(gè)接口是一個(gè)既定的,只要這個(gè) “模組” 滿足這個(gè)接口的裝置都可以被超人所利用,可以提升、增加超人的某一種能力。這種由外部負(fù)責(zé)其依賴需求的行為,我們可以稱其為 “控制反轉(zhuǎn)(IoC)”。

工廠模式,依賴轉(zhuǎn)移!

當(dāng)然,實(shí)現(xiàn)控制反轉(zhuǎn)的方法有幾種。在這之前,不如我們先了解一些好玩的東西。

我們可以想到,組件、工具(或者超人的模組),是一種可被生產(chǎn)的玩意兒,生產(chǎn)的地方當(dāng)然是 “工廠(Factory)”,于是有人就提出了這樣一種模式: 工廠模式

工廠模式,顧名思義,就是一個(gè)類所依賴的外部事物的實(shí)例,都可以被一個(gè)或多個(gè) “工廠” 創(chuàng)建的這樣一種開發(fā)模式,就是 “工廠模式”。

我們?yōu)榱私o超人制造超能力模組,我們創(chuàng)建了一個(gè)工廠,它可以制造各種各樣的模組,且僅需要通過一個(gè)方法:

class SuperModuleFactory
{
    public function makeModule($moduleName, $options)
    {
        switch ($moduleName) {
            case "Fight":   return new Fight($options[0], $options[1]);
            case "Force":   return new Force($options[0]);
            case "Shot":    return new Shot($options[0], $options[1], $options[2]);
        }
    }
}

這時(shí)候,超人 創(chuàng)建之初就可以使用這個(gè)工廠!

class Superman
{
    protected $power;

    public function __construct()
    {
        // 初始化工廠
        $factory = new SuperModuleFactory;

        // 通過工廠提供的方法制造需要的模塊
        $this->power = $factory->makeModule("Fight", [9, 100]);
        // $this->power = $factory->makeModule("Force", [45]);
        // $this->power = $factory->makeModule("Shot", [99, 50, 2]);
        /*
        $this->power = array(
            $factory->makeModule("Force", [45]),
            $factory->makeModule("Shot", [99, 50, 2])
        );
        */
    }
}

可以看得出,我們不再需要在超人初始化之初,去初始化許多第三方類,只需初始化一個(gè)工廠類,即可滿足需求。但這樣似乎和以前區(qū)別不大,只是沒有那么多 new 關(guān)鍵字。其實(shí)我們稍微改造一下這個(gè)類,你就明白,工廠類的真正意義和價(jià)值了。

class Superman
{
    protected $power;

    public function __construct(array $modules)
    {
        // 初始化工廠
        $factory = new SuperModuleFactory;

        // 通過工廠提供的方法制造需要的模塊
        foreach ($modules as $moduleName => $moduleOptions) {
            $this->power[] = $factory->makeModule($moduleName, $moduleOptions);
        }
    }
}

// 創(chuàng)建超人
$superman = new Superman([
    "Fight" => [9, 100], 
    "Shot" => [99, 50, 2]
    ]);

現(xiàn)在修改的結(jié)果令人滿意。現(xiàn)在,“超人” 的創(chuàng)建不再依賴任何一個(gè) “超能力” 的類,我們?nèi)缛粜薷牧嘶蛘咴黾恿诵碌某芰Γ恍枰槍?duì)修改 SuperModuleFactory 即可。擴(kuò)充超能力的同時(shí)不再需要重新編輯超人的類文件,使得我們變得很輕松。但是,這才剛剛開始。

再進(jìn)一步!IoC 容器的重要組成 —— 依賴注入!

由 “超人” 對(duì) “超能力” 的依賴變成 “超人” 對(duì) “超能力模組工廠” 的依賴后,對(duì)付小怪獸們變得更加得心應(yīng)手。但這也正如你所看到的,依賴并未解除,只是由原來對(duì)多個(gè)外部的依賴變成了對(duì)一個(gè) “工廠” 的依賴。假如工廠出了點(diǎn)麻煩,問題變得就很棘手。

其實(shí)大多數(shù)情況下,工廠模式已經(jīng)足夠了。工廠模式的缺點(diǎn)就是:接口未知(即沒有一個(gè)很好的契約模型,關(guān)于這個(gè)我馬上會(huì)有解釋)、產(chǎn)生對(duì)象類型單一。總之就是,還是不夠靈活。雖然如此,工廠模式依舊十分優(yōu)秀,并且適用于絕大多數(shù)情況。不過我們?yōu)榱酥v解后面的 依賴注入 ,這里就先夸大一下工廠模式的缺陷咯。

我們知道,超人依賴的模組,我們要求有統(tǒng)一的接口,這樣才能和超人身上的注入接口對(duì)接,最終起到提升超能力的效果。

事實(shí)上,我之前說謊了,不僅僅只有一堆小怪獸,還有更多的大怪獸。嘿嘿。額,這時(shí)候似乎工廠的生產(chǎn)能力顯得有些不足 —— 由于工廠模式下,所有的模組都已經(jīng)在工廠類中安排好了,如果有新的、高級(jí)的模組加入,我們必須修改工廠類(好比增加新的生產(chǎn)線):

class SuperModuleFactory
{
    public function makeModule($moduleName, $options)
    {
        switch ($moduleName) {
            case "Fight":   return new Fight($options[0], $options[1]);
            case "Force":   return new Force($options[0]);
            case "Shot":    return new Shot($options[0], $options[1], $options[2]);
            // case "more": .......
            // case "and more": .......
            // case "and more": .......
            // case "oh no! its too many!": .......
        }
    }
}

看到?jīng)]。。。噩夢般的感受!

其實(shí)靈感就差一步!你可能會(huì)想到更為靈活的辦法!對(duì),下一步就是我們今天的主要配角 —— DI (依賴注入)

由于對(duì)超能力模組的需求不斷增大,我們需要集合整個(gè)世界的高智商人才,一起解決問題,不應(yīng)該僅僅只有幾個(gè)工廠壟斷負(fù)責(zé)。不過高智商人才們都非常自負(fù),認(rèn)為自己的想法是對(duì)的,創(chuàng)造出的超能力模組沒有統(tǒng)一的接口,自然而然無法被正常使用。這時(shí)我們需要提出一種契約,這樣無論是誰創(chuàng)造出的模組,都符合這樣的接口,自然就可被正常使用。

interface SuperModuleInterface
{
    /**
     * 超能力激活方法
     *
     * 任何一個(gè)超能力都得有該方法,并擁有一個(gè)參數(shù)
     *@param array $target 針對(duì)目標(biāo),可以是一個(gè)或多個(gè),自己或他人
     */
    public function activate(array $target);
}
上文中,我們定下了一個(gè)接口 (超能力模組的規(guī)范、契約),所有被創(chuàng)造的模組必須遵守該規(guī)范,才能被生產(chǎn)。

其實(shí),這就是 php 中 接口( interface ) 的用處和意義!很多人覺得,為什么 php 需要接口這種東西?難道不是 java 、 C# 之類的語言才有的嗎?這么說,只要是一個(gè)正常的面向?qū)ο缶幊陶Z言(雖然 php 可以面向過程),都應(yīng)該具備這一特性。因?yàn)橐粋€(gè) 對(duì)象(object) 本身是由他的模板或者原型 —— 類 (class) ,經(jīng)過實(shí)例化后產(chǎn)生的一個(gè)具體事物,而有時(shí)候,實(shí)現(xiàn)統(tǒng)一種方法且不同功能(或特性)的時(shí)候,會(huì)存在很多的類(class),這時(shí)候就需要有一個(gè)契約,讓大家編寫出可以被隨時(shí)替換卻不會(huì)產(chǎn)生影響的接口。這種由編程語言本身提出的硬性規(guī)范,會(huì)增加更多優(yōu)秀的特性。

雖然有些繞,但通過我們接下來的實(shí)例,大家會(huì)慢慢領(lǐng)會(huì)接口帶來的好處。

這時(shí)候,那些提出更好的超能力模組的高智商人才,遵循這個(gè)接口,創(chuàng)建了下述(模組)類:

/**
 * X-超能量
 */
class XPower implements SuperModuleInterface
{
    public function activate(array $target)
    {
        // 這只是個(gè)例子。。具體自行腦補(bǔ)
    }
}

/**
 * 終極炸彈 (就這么俗)
 */
class UltraBomb implements SuperModuleInterface
{
    public function activate(array $target)
    {
        // 這只是個(gè)例子。。具體自行腦補(bǔ)
    }
}

同時(shí),為了防止有些 “磚家” 自作聰明,或者一些叛徒惡意搗蛋,不遵守契約胡亂制造模組,影響超人,我們對(duì)超人初始化的方法進(jìn)行改造:

class Superman
{
    protected $module;

    public function __construct(SuperModuleInterface $module)
    {
        $this->module = $module
    }
}

改造完畢!現(xiàn)在,當(dāng)我們初始化 “超人” 類的時(shí)候,提供的模組實(shí)例必須是一個(gè) SuperModuleInterface 接口的實(shí)現(xiàn)。否則就會(huì)提示錯(cuò)誤。

正是由于超人的創(chuàng)造變得容易,一個(gè)超人也就不需要太多的超能力,我們可以創(chuàng)造多個(gè)超人,并分別注入需要的超能力模組即可。這樣的話,雖然一個(gè)超人只有一個(gè)超能力,但超人更容易變多,我們也不怕怪獸啦!

現(xiàn)在有人疑惑了,你要講的 依賴注入 呢?

其實(shí),上面講的內(nèi)容,正是依賴注入。

什么叫做 依賴注入

本文從開頭到現(xiàn)在提到的一系列依賴,只要不是由內(nèi)部生產(chǎn)(比如初始化、構(gòu)造函數(shù) __construct 中通過工廠方法、自行手動(dòng) new 的),而是由外部以參數(shù)或其他形式注入的,都屬于 依賴注入(DI) 。是不是豁然開朗?事實(shí)上,就是這么簡單。下面就是一個(gè)典型的依賴注入:

// 超能力模組
$superModule = new XPower;

// 初始化一個(gè)超人,并注入一個(gè)超能力模組依賴
$superMan = new Superman($superModule);

關(guān)于依賴注入這個(gè)本文的主要配角,也就這么多需要講的。理解了依賴注入,我們就可以繼續(xù)深入問題。慢慢走近今天的主角……

更為先進(jìn)的工廠 —— IoC 容器!

剛剛列了一段代碼:

$superModule = new XPower;

$superMan = new Superman($superModule);

讀者應(yīng)該看出來了,手動(dòng)的創(chuàng)建了一個(gè)超能力模組、手動(dòng)的創(chuàng)建超人并注入了剛剛創(chuàng)建超能力模組。呵呵,手動(dòng)。

現(xiàn)代社會(huì),應(yīng)該是高效率的生產(chǎn),干凈的車間,完美的自動(dòng)化裝配。

一群怪獸來了,如此低效率產(chǎn)出超人是不現(xiàn)實(shí),我們需要自動(dòng)化 —— 最多一條指令,千軍萬馬來相見。我們需要一種高級(jí)的生產(chǎn)車間,我們只需要向生產(chǎn)車間提交一個(gè)腳本,工廠便能夠通過指令自動(dòng)化生產(chǎn)。這種更為高級(jí)的工廠,就是工廠模式的升華 —— IoC 容器

class Container
{
    protected $binds;

    protected $instances;

    public function bind($abstract, $concrete)
    {
        if ($concrete instanceof Closure) {
            $this->binds[$abstract] = $concrete;
        } else {
            $this->instances[$abstract] = $concrete;
        }
    }

    public function make($abstract, $parameters = [])
    {
        if (isset($this->instances[$abstract])) {
            return $this->instances[$abstract];
        }

        array_unshift($parameters, $this);

        return call_user_func_array($this->binds[$abstract], $parameters);
    }
}

這時(shí)候,一個(gè)十分粗糙的容器就誕生了。現(xiàn)在的確很簡陋,但不妨礙我們進(jìn)一步提升他。先著眼現(xiàn)在,看看這個(gè)容器如何使用吧!

// 創(chuàng)建一個(gè)容器(后面稱作超級(jí)工廠)
$container = new Container;

// 向該 超級(jí)工廠 添加 超人 的生產(chǎn)腳本
$container->bind("superman", function($container, $moduleName) {
    return new Superman($container->make($moduleName));
});

// 向該 超級(jí)工廠 添加 超能力模組 的生產(chǎn)腳本
$container->bind("xpower", function($container) {
    return new XPower;
});

// 同上
$container->bind("ultrabomb", function($container) {
    return new UltraBomb;
});

// ******************  華麗麗的分割線  **********************
// 開始啟動(dòng)生產(chǎn)
$superman_1 = $container->make("superman", ["xpower"]);
$superman_2 = $container->make("superman", ["ultrabomb"]);
$superman_3 = $container->make("superman", ["xpower"]);
// ...隨意添加

看到?jīng)]?通過最初的 綁定(bind) 操作,我們向 超級(jí)工廠 注冊(cè)了一些生產(chǎn)腳本,這些生產(chǎn)腳本在生產(chǎn)指令下達(dá)之時(shí)便會(huì)執(zhí)行。發(fā)現(xiàn)沒有?我們徹底的解除了 超人 與 超能力模組 的依賴關(guān)系,更重要的是,容器類也絲毫沒有和他們產(chǎn)生任何依賴!我們通過注冊(cè)、綁定的方式向容器中添加一段可以被執(zhí)行的回調(diào)(可以是匿名函數(shù)、非匿名函數(shù)、類的方法)作為生產(chǎn)一個(gè)類的實(shí)例的 腳本 ,只有在真正的 生產(chǎn)(make) 操作被調(diào)用執(zhí)行時(shí),才會(huì)觸發(fā)。

這樣一種方式,使得我們更容易在創(chuàng)建一個(gè)實(shí)例的同時(shí)解決其依賴關(guān)系,并且更加靈活。當(dāng)有新的需求,只需另外綁定一個(gè)“生產(chǎn)腳本”即可。

實(shí)際上,真正的 IoC 容器更為高級(jí)。我們現(xiàn)在的例子中,還是需要手動(dòng)提供超人所需要的模組參數(shù),但真正的 IoC 容器會(huì)根據(jù)類的依賴需求,自動(dòng)在注冊(cè)、綁定的一堆實(shí)例中搜尋符合的依賴需求,并自動(dòng)注入到構(gòu)造函數(shù)參數(shù)中去。Laravel 框架的服務(wù)容器正是這么做的。實(shí)現(xiàn)這種功能其實(shí)理論上并不麻煩,但我并不會(huì)在本文中寫出,因?yàn)椤覒械脤憽?p>不過我告訴大家,這種自動(dòng)搜尋依賴需求的功能,是通過 反射(Reflection) 實(shí)現(xiàn)的,恰好的,php 完美的支持反射機(jī)制!關(guān)于反射,php 官方文檔有詳細(xì)的資料,并且中文翻譯基本覆蓋,足夠?qū)W習(xí)和研究!

http://php.net/manual/zh/book...

現(xiàn)在,到目前為止,我們已經(jīng)不再懼怕怪獸們了。高智商人才集思廣益,井井有條,根據(jù)接口契約創(chuàng)造規(guī)范的超能力模組。超人開始批量產(chǎn)出。最終,人人都是超人,你也可以是哦

回歸正常世界。我們開始重新審視 laravel 的核心。

現(xiàn)在,我們開始慢慢解讀 laravel 的核心。其實(shí),laravel 的核心就是一個(gè) IoC 容器,也恰好是我之前所說的高級(jí)的 IoC 容器。

可以說,laravel 的核心本身十分輕量,并沒有什么很神奇很實(shí)質(zhì)性的應(yīng)用功能。很多人用到的各種功能模塊比如 Route(路由)Eloquent ORM(數(shù)據(jù)庫 ORM 組件)Request and Response(請(qǐng)求和響應(yīng))等等等等,實(shí)際上都是與核心無關(guān)的類模塊提供的,這些類從注冊(cè)到實(shí)例化,最終被你所使用,其實(shí)都是 laravel 的服務(wù)容器負(fù)責(zé)的。

我們以大家最常見的 Route 類作為例子。大家可能經(jīng)常見到路由定義是這樣的:

Route::get("/", function() {
    // bla bla bla...
});

實(shí)際上, Route 類被定義在這個(gè)命名空間:IlluminateRoutingRouter,文件 vendor/laravel/framework/src/Illuminate/Routing/Router.php

我們通過打開發(fā)現(xiàn),這個(gè)類的這一系列方法,如 getpostany 等都不是靜態(tài)(static)方法,這是怎么一回事兒?不要急,我們繼續(xù)。

服務(wù)提供者

我們?cè)谇拔慕榻B IoC 容器的部分中,提到了,一個(gè)類需要綁定、注冊(cè)至容器中,才能被“制造”。

對(duì),一個(gè)類要被容器所能夠提取,必須要先注冊(cè)至這個(gè)容器。既然 laravel 稱這個(gè)容器叫做服務(wù)容器,那么我們需要某個(gè)服務(wù),就得先注冊(cè)、綁定這個(gè)服務(wù)到容器,那么提供服務(wù)并綁定服務(wù)至容器的東西,就是 服務(wù)提供者(ServiceProvider)

雖然,綁定一個(gè)類到容器不一定非要通過 服務(wù)提供者(ServiceProvider)

但是,我們知道,有時(shí)候我們的類、模塊會(huì)有需要其他類和組件的情況,為了保證初始化階段不會(huì)出現(xiàn)所需要的模塊和組件沒有注冊(cè)的情況,laravel 將注冊(cè)和初始化行為進(jìn)行拆分,注冊(cè)的時(shí)候就只能注冊(cè),初始化的時(shí)候就是初始化。拆分后的產(chǎn)物就是現(xiàn)在的 服務(wù)提供者

服務(wù)提供者主要分為兩個(gè)部分,register(注冊(cè))boot(引導(dǎo)、初始化),具體參考文檔。register 負(fù)責(zé)進(jìn)行向容器注冊(cè)“腳本”,但要注意注冊(cè)部分不要有對(duì)未知事物的依賴,如果有,就要移步至 boot 部分。

Facade

我們現(xiàn)在解答之前關(guān)于 Route 的方法為何能以靜態(tài)方法訪問的問題。實(shí)際上這個(gè)問題文檔上有寫,簡單說來就是模擬一個(gè)類,提供一個(gè)靜態(tài)魔術(shù)方法__callStatic,并將該靜態(tài)方法映射到真正的方法上。

我們使用的 Route 類實(shí)際上是 IlluminateSupportFacadesRoute 通過 class_alias() 函數(shù)創(chuàng)造的 別名 而已,這個(gè)類被定義在文件 vendor/laravel/framework/src/Illuminate/Support/Facades/Route.php

我們打開文件一看……誒?怎么只有這么簡單的一段代碼呢?


其實(shí)仔細(xì)看,會(huì)發(fā)現(xiàn)這個(gè)類繼承了一個(gè)叫做 Facade 的類,到這里謎底差不多要解開了。

上述簡單的定義中,我們看到了 getFacadeAccessor 方法返回了一個(gè) route,這是什么意思呢?事實(shí)上,這個(gè)值被一個(gè) ServiceProvider 注冊(cè)過,大家應(yīng)該知道注冊(cè)了個(gè)什么,當(dāng)然是那個(gè)真正的路由類!

有人會(huì)問,F(xiàn)acade 是怎么實(shí)現(xiàn)的。我并不想說得太細(xì),一個(gè)是我懶,另一個(gè)原因就是,自己發(fā)現(xiàn)一些東西更容易理解,并不容易忘記。很多細(xì)節(jié)我已經(jīng)說了,建議大家自行去研究。

至此,我們已經(jīng)講的差不多了。

和平!我們?cè)摽偨Y(jié)總結(jié)了!

無論如何,世界和平了。

這里要總結(jié)的內(nèi)容就是,其實(shí)很多事情并不復(fù)雜,怕的是復(fù)雜的理論內(nèi)容。我覺得很多東西一旦想通也就那么回事兒。很多人覺得 laravel 這不好那不好、這里難哪里難,我只能說,laravel 的確不是一流和優(yōu)秀的框架,說 laravel 是一流、優(yōu)秀的框架的人,不是 laravel 的粉絲那么就是跟風(fēng)炒作。Laravel 最大的特點(diǎn)和優(yōu)秀之處就是使用了很多 php 比較新(實(shí)際上并不新)的概念和技術(shù)(也就一堆語法糖)而已。因此 laravel 的確符合一個(gè)適宜學(xué)習(xí)的框架。Laravel 的構(gòu)思的確和其他框架有很大不同,這也要求學(xué)習(xí)他的人必須熟練 php,并 基礎(chǔ)扎實(shí)!如果你覺得學(xué) laravel 框架十分困難,那么原因只有一個(gè):你 php 基礎(chǔ)不好。

另外,善于利用命名空間和面向?qū)ο蟮闹T多特性,去追尋一些東西,你會(huì)發(fā)現(xiàn),原來這一切這么容易。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/31567.html

相關(guān)文章

  • 深入理解IoC控制反轉(zhuǎn))、DI依賴注入

    摘要:引述最近看設(shè)計(jì)模式以及代碼,對(duì)于控制反轉(zhuǎn)以及依賴注入這些概念非常困惑,于是找了一些資料,以下是對(duì)于控制反轉(zhuǎn)的一下理解。其中最常見的方式叫做依賴注入,簡稱,還有一種方式叫依賴查找。在軟件工程中,依賴注入是種實(shí)現(xiàn)控制反轉(zhuǎn)用于解決依賴性設(shè)計(jì)模式。 引述 最近看設(shè)計(jì)模式以及l(fā)aravel代碼,對(duì)于控制反轉(zhuǎn)以及依賴注入這些概念非常困惑,于是找了一些資料,以下是對(duì)于控制反轉(zhuǎn)的一下理解。 概念 Io...

    xcc3641 評(píng)論0 收藏0
  • 深入理解依賴注入

    摘要:上面這部分代碼不變,還是通過在構(gòu)造器中傳入依賴的方式初始化依賴調(diào)用這里,調(diào)用方無需了解內(nèi)部對(duì)的依賴。而配置一般用于上自動(dòng)掃描并注入的代碼如下這里只給出直接在依賴對(duì)象上添加注解的形式,還可以通過構(gòu)造器和注入依賴,這里就不多說了。 前言 相信所有面試java開發(fā)的童鞋一定都被問到過是否使用過Spring,是否了解其IOC容器,為什么不直接使用工廠模式,以及究竟IOC和DI區(qū)別在于哪里這種問...

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

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

    atinosun 評(píng)論0 收藏0
  • 深入剖析 Laravel 服務(wù)容器

    摘要:劃下重點(diǎn),服務(wù)容器是用于管理類的依賴和執(zhí)行依賴注入的工具。類的實(shí)例化及其依賴的注入,完全由服務(wù)容器自動(dòng)的去完成。 本文首發(fā)于 深入剖析 Laravel 服務(wù)容器,轉(zhuǎn)載請(qǐng)注明出處。喜歡的朋友不要吝嗇你們的贊同,謝謝。 之前在 深度挖掘 Laravel 生命周期 一文中,我們有去探究 Laravel 究竟是如何接收 HTTP 請(qǐng)求,又是如何生成響應(yīng)并最終呈現(xiàn)給用戶的工作原理。 本章將帶領(lǐng)大...

    abson 評(píng)論0 收藏0
  • Spring IoC學(xué)習(xí)總結(jié)

    摘要:學(xué)習(xí)總結(jié)學(xué)習(xí)整理的一些筆記,很簡單。大部分認(rèn)為和只是不同的叫法而已。依賴注入的兩種方式和注解使用注釋驅(qū)動(dòng)的功能源碼剖析 Spring IoC學(xué)習(xí)總結(jié) 學(xué)習(xí)spring Ioc整理的一些筆記,很簡單。分享給大家。 IoC 基本概念 在這之前,我們先記住一句話。好萊塢原則:Dont call us, we will call you.其實(shí)這句話很恰當(dāng)?shù)匦稳萘朔崔D(zhuǎn)的意味;Ioc, Inve...

    silencezwm 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<