成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

Laravel深入學(xué)習(xí)6 - 應(yīng)用體系結(jié)構(gòu):解耦事件處理器

HackerShell / 1673人閱讀

摘要:別堵塞了傳輸層大多數(shù)事件處理器被當(dāng)作傳輸層組件。解耦事件處理器開(kāi)始本命題前,我們來(lái)使用一個(gè)示例。假想下把隊(duì)列處理器用來(lái)發(fā)送消息給用戶。盡量避免在事件處理器中摻雜太多的業(yè)務(wù)邏輯。

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

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

應(yīng)用體系結(jié)構(gòu):解耦事件處理器 介紹

現(xiàn)在我們已經(jīng)介紹了很多使用Laravel 4構(gòu)建健壯應(yīng)用的特性,下面來(lái)深入挖掘更多的細(xì)節(jié)。本章我們將討論諸如隊(duì)列、事件這些眾多事件處理器的解耦,也包括類(lèi)似“類(lèi)事件”結(jié)構(gòu)的路由過(guò)濾。

別堵塞了傳輸層

大多數(shù)“事件處理器”被當(dāng)作_傳輸層_組件。換言之,隊(duì)列處理、事件觸發(fā)器、或者一個(gè)外來(lái)請(qǐng)求都被用來(lái)調(diào)用某些調(diào)用處理。要像處理控制器一樣處理這些事件處理器,并避免在其中涉及太多業(yè)務(wù)邏輯。

解耦事件處理器

開(kāi)始本命題前,我們來(lái)使用一個(gè)示例。假想下把隊(duì)列處理器用來(lái)發(fā)送SMS消息給用戶。在發(fā)送消息之后,處理器講發(fā)送了的消息記錄成歷史以便我們知道有哪些用戶收到了這些消息。代碼實(shí)現(xiàn)如下:

class SendSMS{

    public function fire($job, $data)
    {
        $twilio = new Twilio_SMS($apiKey);

        $twilio->sendTextMessage(array(
            "to"=> $data["user"]["phone_number"],
            "message"=> $data["message"],
        ));

        $user = User::find($data["user"]["id"]);

        $user->messages()->create(array(
            "to"=> $data["user"]["phone_number"],
            "message"=> $data["message"],
        ));

        $job->delete();
    }

}

僅測(cè)試這塊代碼,就可能遇到一些問(wèn)題。首先,測(cè)試?yán)щy。Twilio_SMS類(lèi)是在fire方法中實(shí)例化的,這意味著我們無(wú)法使用注入的方式模擬服務(wù)。其次,在處理器中我們直接用到了Eloquent模型,這就給測(cè)試帶來(lái)了另外一個(gè)問(wèn)題,我們必須在方法中進(jìn)行真正的數(shù)據(jù)庫(kù)訪問(wèn)。最后,我們?cè)陉?duì)列之外無(wú)法進(jìn)行SMS消息發(fā)送。我們的SMS消息發(fā)送邏輯完全糅合在Laravel隊(duì)列中了。

通過(guò)將邏輯提取到某一“服務(wù)”中的方法,我們可以將應(yīng)用中的SMS消息發(fā)送邏輯從Laravel的隊(duì)列服務(wù)中解耦出來(lái)。從而可以在應(yīng)用中的任何地方發(fā)送消息。當(dāng)我們進(jìn)行了這種解耦處理,這種重構(gòu)也是我們的代碼變得更加具有可測(cè)性。

讓我們來(lái)修改下代碼:

class User extends Eloquent {

    /**
     * Send the User an SMS message
     *
     * @param SmsCourierInterface $courier
     * @param string $message
     * @return SmsMessage
     */
    public function sendSmsMessage(SmsCourierInterface $courier, $message)
    {
        $courier->sendMessage($this->phone_number, $message);

        return $this->sms()->create(array(
            "to"=> $this->phone_number,
            "message"=> $message,
        ));
    }

}

在這個(gè)重構(gòu)的代碼實(shí)例中,我們將發(fā)送消息的邏輯提取到User模型中。同時(shí)向該方法中注入SmsCourierInterface接口實(shí)現(xiàn)邏輯,使我們更好的測(cè)試邏輯中的方方面面。重構(gòu)了短信發(fā)送邏輯之后,再對(duì)隊(duì)列進(jìn)行重構(gòu):

class SendSMS {

    public function __construct(UserRepository $users, SmsCourierInterface $courier)
    {
        $this->users = $users;
        $this->courier = $courier;
    }

    public function fire($job, $data)
    {
        $user = $this->users->find($data["user"]["id"]);

        $user->sendSmsMessage($this->courier, $data["message"]);

        $job->delete();
    }

}

在重構(gòu)的示例中,可以看到,隊(duì)列服務(wù)已經(jīng)足夠輕量。它在隊(duì)列和我們_真正的_應(yīng)用邏輯之間已經(jīng)足夠符合_傳輸層_這個(gè)概念。贊!這意味著我們可以在隊(duì)列之外輕易的發(fā)送消息。最后,讓我們編寫(xiě)一些測(cè)試代碼:

class SmsTest extends PHPUnit_Framework_TestCase {

    public function testUserCanBeSentSmsMessages()
    {
        /**
         * Arrage ...
         */
        $user = Mockery::mock("User[sms]");
        $relation = Mockery::mock("StdClass");
        $courier = Mockery::mock("SmsCourierInterface");

        $user->shouldReceive("sms")->once()->andReturn($relation);

        $relation->shouldReceive("create")->once()->with(array(
            "to" => "555-555-5555",
            "message" => "Test",
        ));

        $courier->shouldReceive("sendMessage")->once()->with(
            "555-555-5555", "Test"
        );

        /**
         * Act ...
         */
        $user->sms_number = "555-555-5555";
        $user->sendMessage($courier, "Test");
    }
}
其他事件處理器

我們可以改進(jìn)很多這種類(lèi)型的“事件處理器”。將他們限定為簡(jiǎn)單的“傳輸層”來(lái)使用,能將復(fù)雜的業(yè)務(wù)邏輯很好的組織和解耦到框架之外。為了鞏固下這種思想,下面我們舉例一個(gè)路由過(guò)濾器,用它來(lái)驗(yàn)證用戶是否為我們的“高級(jí)”訂閱用戶。

Route::filter("premium", function()
{
    return Auth::user() && Auth::user()->plan == "premium";
});

乍看像是沒(méi)什么問(wèn)題。這么小的代碼能有啥問(wèn)題呢?然而,在這么小的過(guò)濾中,也能意識(shí)到我們將應(yīng)用的實(shí)現(xiàn)細(xì)節(jié)暴漏了出來(lái)。注意,我們?cè)谶^(guò)濾中進(jìn)行對(duì)plan屬性進(jìn)行了檢測(cè)。“級(jí)別”的檢測(cè)邏輯層緊緊的揉進(jìn)了路由、傳輸層。如果我們將“高級(jí)”訂閱用戶的套餐存放到數(shù)據(jù)庫(kù)或者用戶模型中,這里又必須對(duì)我們的路由過(guò)濾器進(jìn)行修改!

相應(yīng)的,做些小的改編:

Route::filter("premium", function()
{
    return Auth::user() && Auth::user()->isPremium();
});

這樣小的改編帶來(lái)的效果是明顯的,付出的代價(jià)也是小的。通過(guò)在模型中對(duì)用戶是否屬于高級(jí)訂閱用戶的判斷,我們將路由中的檢測(cè)邏輯解耦了出來(lái)。我們的過(guò)濾程序不在負(fù)責(zé)檢測(cè)用戶訂閱級(jí)別的職責(zé)。相應(yīng)的,它只需簡(jiǎn)單的詢問(wèn)用戶模型即可?,F(xiàn)在,如果訂閱級(jí)別的判斷存放在數(shù)據(jù)庫(kù)中,路由過(guò)濾不需要更改任何代碼!

該誰(shuí)負(fù)責(zé)?

我們又一次討論了_職責(zé)_的概念。牢記,一個(gè)類(lèi)應(yīng)有的職責(zé)是什么,和他涉及的范圍是明確的。盡量避免在事件處理器中摻雜太多的業(yè)務(wù)邏輯。

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

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

相關(guān)文章

  • Laravel深入學(xué)習(xí)5 - 應(yīng)用架構(gòu)

    摘要:控制只是用來(lái)接收請(qǐng)求并請(qǐng)求邏輯處理類(lèi)。事實(shí)上,業(yè)務(wù)邏輯無(wú)需感知網(wǎng)絡(luò),網(wǎng)絡(luò)僅僅接入應(yīng)用的傳輸機(jī)制,他不應(yīng)超出應(yīng)用中的路由和控制器的范疇。職責(zé)分離是編寫(xiě)健壯應(yīng)用的關(guān)鍵。其他通常,類(lèi)庫(kù)應(yīng)該以規(guī)范組織在我們的應(yīng)用中。 聲明:本文并非博主原創(chuàng),而是來(lái)自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%的原汁性,另...

    lixiang 評(píng)論0 收藏0
  • Laravel最佳實(shí)踐--事件驅(qū)動(dòng)編程

    摘要:事件驅(qū)動(dòng)編程是圖形用戶界面和其他應(yīng)用程序例如應(yīng)用程序中使用的主要范例,用于執(zhí)行某些操作來(lái)響應(yīng)用戶輸入。我們來(lái)看一下事件驅(qū)動(dòng)編程帶來(lái)的收益?,F(xiàn)在讓我們看看采用事件驅(qū)動(dòng)編程方法如何實(shí)現(xiàn)上述相同的功能。 在這篇文章中我們將了解到什么是事件驅(qū)動(dòng)編程以及在Laravel中如何開(kāi)始構(gòu)建一個(gè)事件驅(qū)動(dòng)應(yīng)用,同時(shí)我們還將看到如何通過(guò)事件驅(qū)動(dòng)編程來(lái)對(duì)應(yīng)用程序的邏輯進(jìn)行解耦。 在開(kāi)始之前,先說(shuō)明一下這篇文章...

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

    摘要:劃下重點(diǎn),服務(wù)容器是用于管理類(lèi)的依賴和執(zhí)行依賴注入的工具。類(lèi)的實(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í)4 - 服務(wù)提供器

    摘要:一個(gè)服務(wù)提供器必須包含至少一種方法。服務(wù)提供器一旦被注冊(cè),就可被用于程序的各個(gè)地方。注意服務(wù)提供器的變量來(lái)自類(lèi)中。啟動(dòng)服務(wù)當(dāng)所有的服務(wù)提供器注冊(cè)之后,他們就變成了已啟動(dòng)狀態(tài)。再次提示,把服務(wù)提供器作為一種組織工具來(lái)使用。 聲明:本文并非博主原創(chuàng),而是來(lái)自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%...

    daryl 評(píng)論0 收藏0
  • Laravel深入學(xué)習(xí)8 - 單一責(zé)任原則

    摘要:它是良好應(yīng)用設(shè)計(jì)的大原則,包含單一責(zé)任原則開(kāi)放封閉原則里氏替換原則接口分離原則依賴倒置原則讓我們通過(guò)代碼示例來(lái)深究下這五個(gè)原則。實(shí)探單一責(zé)任原則代表一個(gè)類(lèi)有且僅有一個(gè)改變的原因,換言之,一個(gè)類(lèi)的職責(zé)范疇是嚴(yán)謹(jǐn)明確的。 聲明:本文并非博主原創(chuàng),而是來(lái)自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%的原...

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

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

0條評(píng)論

HackerShell

|高級(jí)講師

TA的文章

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