成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Laravel深入學(xué)習(xí)1 - 依賴注入

sunsmell / 3462人閱讀

摘要:然而,我們需要注意的是僅是軟件設(shè)計(jì)模式依賴注入的一種便利的實(shí)現(xiàn)形式。容器本身不是依賴注入的必要條件,在框架他只是讓其變得更加簡便。首先,讓我們探索下為什么依賴注入是有益的。繼續(xù)深入讓我們通過另一個(gè)示例來加深對(duì)依賴注入的理解。

聲明:本文并非博主原創(chuàng),而是來自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%的原汁性,另外因?yàn)槭抢斫夥g,肯定會(huì)有錯(cuò)誤的地方,歡迎指正。

歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處,謝謝!

依賴注入 問題所在

Laravel框架的基礎(chǔ)在于其IoC容器。要想真正了解框架的核心,需要對(duì)容器有一定的概念。然而,我們需要注意的是IoC僅是軟件設(shè)計(jì)模式:依賴注入的一種便利的實(shí)現(xiàn)形式。容器本身不是依賴注入的必要條件,在框架他只是讓其變得更加簡便。

首先,讓我們探索下為什么依賴注入是有益的??紤]到如下代碼中的類和方法:

class UserController extends BaseController {

    public function getIndex()
    {
        $users = User::all();

        return View::make("users.index", compact("users"));
    }
}

代碼簡潔易懂,但是在沒有連接到數(shù)據(jù)庫的情況下,我們是無法進(jìn)行測(cè)試的。換句話說, Eloquent ORM 被緊密耦合到控制器中了。在未連接數(shù)據(jù)庫的情況下,我們無法測(cè)試當(dāng)前引用了Eloquent ORM的控制器的方法。這段代碼同樣違背了軟件設(shè)計(jì)原則 關(guān)注點(diǎn)分離(SoC) 。簡言之:控制器知道的太多。控制器無需知道數(shù)據(jù)_從何而來_,只需關(guān)注如何接入;無需關(guān)心數(shù)據(jù)庫在MySQL中是否可用,而只關(guān)心數(shù)據(jù)在_某處_可用。

關(guān)注點(diǎn)分離(Separation Of Concerns):

每個(gè)類都應(yīng)有其單一的職責(zé),并且這個(gè)職責(zé)由這個(gè)類完全封裝

所以,將web層(controller)從數(shù)據(jù)層解耦分離出來會(huì)是有益的。這在我們對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ)遷移時(shí)是有利的,也會(huì)使代碼的測(cè)試更為簡單。將“Web”認(rèn)為是到“真正”應(yīng)用的傳輸層。

想象一下,應(yīng)用是一臺(tái)有著多種電纜接口的顯示器。我們能通過HDMI,VGA或者DVI接入顯示功能。也可將應(yīng)用比喻成你接入互聯(lián)網(wǎng)的電纜。顯示器的主要功能大部分依賴著電纜。而電纜僅僅是一種類似HTTP接入你應(yīng)用的傳輸部件。所以我們不想將這部分內(nèi)容(控制器)和應(yīng)用邏輯糅合在一塊。這種做法可以允許任何傳輸層,比如API或者移動(dòng)應(yīng)用程序來接入我們的應(yīng)用邏輯。

所以,我們?cè)俅巫⑷胍粋€(gè)存儲(chǔ)類,來代替現(xiàn)有將控制器和Eloquent ORM糅合在一塊的做法。

契約式設(shè)計(jì)

http://www.jdon.com/36303

首先,我們定義一個(gè)接口和相應(yīng)的實(shí)現(xiàn):

interface UserRepositoryInterface {

    public function all();

}

class DbUserRepository implements UserRepositoryInterface {

    public function all()
    {
        return User::all()->toArray();
    }
}

接下來,我們向控制器中注入此接口的實(shí)現(xiàn)。

class UserController extends BaseController {

    public function __construct(UserRepositoryInterface $users)
    {
        $this->users = $users;
    }

    public function getIndex()
    {
        $users = $this->users->all();

        return View::make("users.index", compact("users"));
    }
}

現(xiàn)在,我們的控制器根本不曉得數(shù)據(jù)存儲(chǔ)在何處,無知是福?。∥覀兊臄?shù)據(jù)可以來自MySQL,MongoDB,甚至是來自Redis。我們不知道這其中的區(qū)別,也不需要關(guān)心。僅僅這一點(diǎn)小小的改變,我們就可以將web層從數(shù)據(jù)層脫離,當(dāng)然當(dāng)數(shù)據(jù)存儲(chǔ)改變時(shí)也不會(huì)影響到我們。

服從邊限

記得服從職責(zé)限定。應(yīng)用中控制器和路由是HTTP和程序交互的中簡介,在大型程序中,不能將他們糅合到你的主要邏輯中。

為了鞏固上面的知識(shí),我們從一個(gè)測(cè)試案例開始。首先,模擬一個(gè)庫并綁定到IoC容器中,然后確??刂破髡_的調(diào)用了該庫:

public function testIndexActionBindsUsersFromRepository()
{
    // Arrange...
    $repository = Mockery::mock("UserRepositoryInterface");
    $repository->shouldReceive("all")->once()->andReturn(array("foo"));
    App::instance("UserRepositoryInterface", $repository);

    // Act...
    $response = $this->action("GET", "UserController@getIndex");

    // Assert...
    $this->assertResponseOk();
    $this->assertViewHas("users", array("foo"));
}

你在模仿我么

示例中,我們使用了Mockery模擬庫,它提供了一套表述簡潔的方法來模仿你的程序。Mockery可通過Composer進(jìn)行安裝。

繼續(xù)深入

讓我們通過另一個(gè)示例來加深對(duì)依賴注入的理解。有這樣一個(gè)場(chǎng)景,我們需要對(duì)用戶賬戶中發(fā)生的財(cái)務(wù)變更用進(jìn)行通知。這里我們定義兩個(gè)接口,或者叫約定。這些約定將會(huì)使需求變更變的很便捷。

interface BillerInterface {
    public function bill(array $user, $amount);
}

interface BillingNotifierInterface {
    public function notify(array $user, $amount);
}

緊接著,我們來實(shí)現(xiàn)BillerInterface接口:

class StripeBiller implements BillerInterface {

    public function __construct(BillingNotifierInterface $notifier)
    {
        $this->notifier = $notifier;
    }

    public function bill(array $user, $amount)
    {
        // Bill the user via Stripe...

        $this->notifier->notify($user, $amount);
    }

}

由于各個(gè)類之間已經(jīng)進(jìn)行了職責(zé)分離,為財(cái)務(wù)賬單(billing)類注入不同的通知程序?qū)?huì)很方便。比如注入短信通知類SmsNotifier或者郵件通知類EmailNotifier。我們的賬單系統(tǒng)不需要考慮賬單通知的實(shí)現(xiàn),只需要根據(jù)約定執(zhí)加載通知即可。凡是遵守約定的賬單,都能實(shí)現(xiàn)對(duì)用戶財(cái)務(wù)變更的通知。此外,不光我們添加方便,我們也可以多帶帶模擬BillingNotifierInterface接口,來測(cè)試賬單系統(tǒng)。

善用接口

接口寫起來看似添加了很多額外的東西,實(shí)際是在加速我們的開發(fā)。我們可以在不實(shí)現(xiàn)接口的情況下,模擬已開發(fā)的接口,來對(duì)整個(gè)底層邏輯進(jìn)行測(cè)試。

那問題來了,怎么實(shí)現(xiàn)依賴注入呢?

$biller = new StripeBiller(new SmsNotifier);

如上,簡單吧,這就是依賴注入。只需要將通知器傳入到賬單系統(tǒng),而不用擔(dān)心通知器的使用。微小的改動(dòng)就能是代碼很清晰,這種清晰的職責(zé)界定設(shè)計(jì),讓我們使代碼維護(hù)簡單,當(dāng)然也方便模擬測(cè)試。

那IoC容器是怎么一回事?依賴注入必須要用到他么?這里當(dāng)然不是!在以后的章節(jié)中,我們會(huì)看到IoC容器只是為了更好的組織管理依賴注入,但它并非必須。只要遵循本章中介紹的設(shè)計(jì)原則,你可以在任何項(xiàng)目中實(shí)現(xiàn)依賴注入,也不用管是否有這樣一個(gè)容器可用。

太多JAVA了吧

很多人指責(zé),在PHP中使用接口把代碼變的太過冗長,太象“JAVA”。你必須定義一個(gè)接口并實(shí)現(xiàn)一個(gè)類,這得多敲多少代碼。

在小而簡的項(xiàng)目中,我承認(rèn)這種批判。這樣的項(xiàng)目中,接口是不必要的,因?yàn)榫湍阕约河?,以后也不?huì)去改。即使架構(gòu)上牛逼的架構(gòu)師也會(huì)說“需求永遠(yuǎn)不會(huì)確定”,但是需要承認(rèn)的是,總有tm那么一些地方就是改不著。

接口在大型項(xiàng)目中是非常有用的,這樣額外的代碼是為了保證未來你代碼的靈活性和可測(cè)試性。當(dāng)你快速切換代碼實(shí)現(xiàn)的時(shí)候,一定會(huì)閃瞎某些人的狗眼。當(dāng)然我們的目的是為了讓代碼能夠適應(yīng)各種操蛋需求的變更。

總之,我們一直提倡“簡潔”架構(gòu)。如果如果你的項(xiàng)目很小,不需要遵循這么多規(guī)范,也別不好意思。代碼敲的怎么爽怎么來。如果不寫接口,也行,以后再說唄,又不是結(jié)婚買房,都tm逼的。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/22563.html

相關(guān)文章

  • 深入剖析 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
  • Laravel深入學(xué)習(xí)2 - 控制反轉(zhuǎn)容器

    摘要:控制反轉(zhuǎn)容器控制反轉(zhuǎn)使依賴注入變得更加便捷。有瑕疵控制反轉(zhuǎn)容器是實(shí)現(xiàn)的控制翻轉(zhuǎn)容器的一種替代方案。容器的獨(dú)立使用即使沒有使用框架,我們?nèi)匀豢梢栽陧?xiàng)目中使用安裝組件來使用的控制反轉(zhuǎn)容器。在沒有給定任何信息的情況下,容器是無法實(shí)例化相關(guān)依賴的。 聲明:本文并非博主原創(chuàng),而是來自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味...

    worldligang 評(píng)論0 收藏0
  • 深入理解控制反轉(zhuǎn)(IoC)和依賴注入(DI)

    摘要:本文一大半內(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ì)象的描...

    HollisChuang 評(píng)論0 收藏0
  • Laravel深入學(xué)習(xí)12 - 依賴倒置原則

    摘要:在改變存儲(chǔ)系統(tǒng)的情況下,必須對(duì)進(jìn)行修改,違背了開放封閉原則。傳統(tǒng)的依賴痛過倒置就能事代碼變得非常靈活,易于改變 聲明:本文并非博主原創(chuàng),而是來自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%的原汁性,另外因?yàn)槭抢斫夥g,肯定會(huì)有錯(cuò)誤的地方,歡迎指正。 歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處,謝謝! 依賴反轉(zhuǎn)原則 ...

    IamDLY 評(píng)論0 收藏0
  • Laravel深入學(xué)習(xí)9 - 開放封閉原則

    摘要:如果在設(shè)計(jì)中,能正確使用開放封閉原則,就能很好的規(guī)避這些問題。開放封閉原則設(shè)計(jì)原則中的開放封閉原則是指代碼對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。實(shí)探我們以上章中的為基礎(chǔ),繼續(xù)來探究開放封閉原則。在進(jìn)一步處理之前,要知道開閉原則并非硬規(guī)定。 聲明:本文并非博主原創(chuàng),而是來自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證9...

    young.li 評(píng)論0 收藏0

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

0條評(píng)論

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