亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Laravel深入學(xué)習(xí)3 - 接口約定

鄒立鵬 / 1070人閱讀

摘要:難道,就沒(méi)有強(qiáng)類(lèi)型特征答案是明確的,肯定有其實(shí)是一種強(qiáng)類(lèi)型和弱類(lèi)型的結(jié)合體。強(qiáng)類(lèi)型語(yǔ)言中,編譯器通常提供編譯檢查錯(cuò)誤的功能,它也是非常有用的。與此同時(shí),強(qiáng)類(lèi)型的代碼看起來(lái)也是很生硬的。

聲明:本文并非博主原創(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)注明出處,謝謝!

接口約定 強(qiáng)類(lèi)型和弱類(lèi)型

Water Fowl 這里我不知道該怎么翻譯,按理解就將他翻譯成弱類(lèi)型?

之前的文章中,涵蓋了依賴注入的基礎(chǔ)知識(shí):什么是依賴注入;如何實(shí)現(xiàn);以及他有什么好處。在舉例的代碼中,也展示了如何將接口注入到類(lèi)之中。在我們繼續(xù)深入之前,有必要深入一下接口相關(guān)的內(nèi)容,因?yàn)楹芏郟HP開(kāi)發(fā)人員對(duì)接口都有相當(dāng)程度的不熟練。

在我成為一個(gè)PHP程序員之前,我是寫(xiě).NET的。難道我喜歡痛苦或者其他什么的么?在.NET中接口無(wú)處不在,事實(shí)上.NET框架的很多核心內(nèi)容就是接口,還有一個(gè)好處:很多象.NET的語(yǔ)言如C#、VB等都是_強(qiáng)類(lèi)型_的。通常,傳入方法的原生對(duì)象,必須預(yù)先定義好相關(guān)的_類(lèi)型_。例如下面的C#代碼:

public int BillUser(User user)
{
    this.biller.bill(user.GetId(), this.amount)
}

我們不僅定義了傳入?yún)?shù)的_類(lèi)型_,函數(shù)返回的類(lèi)型都是已經(jīng)定義好的。C#提倡_安全類(lèi)型_。函數(shù)BillUser方法傳入的參數(shù)必須是User對(duì)象。

PHP是一種_弱類(lèi)型_語(yǔ)言。在弱類(lèi)型語(yǔ)言中,對(duì)象中可用的方法取決于其方法的使用形式,而非方法繼承或者實(shí)現(xiàn)的位置。例如:

public function billUser($user)
{
    $this->biller->bill($user->getId(), $this->amount);
}

我們無(wú)需告訴方法類(lèi)型的參數(shù)是什么,我們可以傳入任意對(duì)象,只要他有getId方法就行。這就是弱類(lèi)型編碼的例子。如果一個(gè)東西看起來(lái)象鴨子,叫聲也象,那么他就是一個(gè)鴨子。換言之,如果一個(gè)對(duì)象象user,行為也象user,那么他就是一個(gè)user對(duì)象。

難道,PHP就沒(méi)有強(qiáng)類(lèi)型特征?答案是明確的,肯定有!PHP其實(shí)是一種強(qiáng)類(lèi)型和弱類(lèi)型的結(jié)合體。為了說(shuō)明這一點(diǎn),我們修改下上例的代碼:

public function billUser(User $user)
{
    $this->biller->bill($user->getId(), $amount);
}

在方法參數(shù)中,加入User約定后,就能確保傳入方法的參數(shù)必須是User的實(shí)例化對(duì)象或者是繼承自User的一個(gè)實(shí)例。

兩種類(lèi)型各有優(yōu)劣。強(qiáng)類(lèi)型語(yǔ)言中,編譯器通常提供編譯檢查錯(cuò)誤的功能,它也是非常有用的。方法的輸入和輸出都是明確的。

與此同時(shí),強(qiáng)類(lèi)型的代碼看起來(lái)也是很生硬的。比如Eluquent ORM中提供的動(dòng)態(tài)方法whereEmailOrName就不能象C#那樣明確參數(shù)和返回值的類(lèi)型。這里不討論孰優(yōu)孰劣,我們各取所長(zhǎng),但是,不假思索的死認(rèn)某一種方式肯定會(huì)埋下很多坑。

示例

接口就是約定,他不包含具體的代碼實(shí)現(xiàn),而定義了對(duì)象需要實(shí)現(xiàn)的一系列的方法。如果一個(gè)對(duì)象實(shí)現(xiàn)了某個(gè)接口,那么這個(gè)接口的方法肯定都能在這個(gè)實(shí)例對(duì)象中使用。通過(guò)約定固化了某些方法的實(shí)現(xiàn),這種_多態(tài)_就能保證語(yǔ)言的類(lèi)型安全。

什么是多態(tài)?

多態(tài)含義很廣,可以理解為一種實(shí)體的多種形式。在本書(shū)中,我們指代接口的多種實(shí)現(xiàn)方式。例如:UserRepositoryInterface可以有MySQL和Redis兩種存儲(chǔ)實(shí)現(xiàn)方式,但是每一種都是UserRepositoryInter接口的實(shí)現(xiàn)。

為了說(shuō)明強(qiáng)類(lèi)型在接口中的靈活和重要性,我們來(lái)實(shí)現(xiàn)如下一個(gè)酒店預(yù)訂的例子:

interface ProviderInterface
{
    public function getLowestPrice($location);
    public function book($location);
}

當(dāng)用戶預(yù)訂房間是,我們想將此事件記錄到系統(tǒng)中。我們?cè)?b>User類(lèi)中添加如下方法:

class User
{
    public function bookLocation(ProviderInterface $provider, $location)
    {
        $amountCharged = $provider->book($location);
        $this->logBookedLocation($location, $amountCharged);
    }
}

我們限定了參數(shù)$provider的類(lèi)型,User類(lèi)中就能假定book方法是可安全調(diào)用的,這就使得bookLocation有較強(qiáng)的操作性,我們不用關(guān)心酒店是如何實(shí)現(xiàn)房間預(yù)訂這一過(guò)程。下面的代碼就能體現(xiàn)這一特性:

$location = "Hilton, Dallas";

$cheapestProvider = $this->findCheapest($location, array(
    new PricelineProvider,
    new OrbitzProvider,
));

$user->bookLocation($cheapestProvider, $location);

贊!我們不用關(guān)心那家酒店最便宜,只需要將他傳入User實(shí)例中就能成功預(yù)訂房間。因?yàn)?b>User對(duì)象要求傳入的參數(shù)是繼承自ProviderInterface的對(duì)象,未來(lái)添加更多的酒店提供商,都能使我們的代碼穩(wěn)定的運(yùn)行。

忘掉細(xì)節(jié)

記住,接口_不實(shí)現(xiàn)_任何細(xì)節(jié),只是簡(jiǎn)單的定義類(lèi)必須實(shí)現(xiàn)的方法。

接口和團(tuán)隊(duì)開(kāi)發(fā)

當(dāng)團(tuán)隊(duì)構(gòu)建大型應(yīng)用時(shí),不同的模塊進(jìn)程是不同的。比如,有人處理數(shù)據(jù)層,有人處理前端web、控制器層。前端開(kāi)發(fā)項(xiàng)測(cè)試自己的控制器,但是后端人員開(kāi)發(fā)進(jìn)度緩慢。但是,如果我們能約定好接口,后端人員只須遵循接口定義:

interface OrderRepositoryInterface 
{
    public function getMostRecent(User $user);
}

一旦約定了接口,前端開(kāi)發(fā)人員,在代碼沒(méi)有實(shí)現(xiàn)的情況下,也能測(cè)試自己的控制器!這樣整個(gè)應(yīng)用中就不用擔(dān)心不同模塊的開(kāi)發(fā)進(jìn)度,也不會(huì)影響到正常的測(cè)試用例的編寫(xiě)。更深一點(diǎn)來(lái)說(shuō),這種方法不會(huì)影響到其他組件的開(kāi)發(fā),做到了無(wú)知是福。我們不需要讓我們的類(lèi)必須知道其他類(lèi)是_怎么_實(shí)現(xiàn)的,只需要知道他_能夠_干什么?,F(xiàn)在,我們已經(jīng)定義了接口,那么我們可以繼續(xù)我們控制器代碼的實(shí)現(xiàn)了:

class OrderController 
{
    public function __construct(OrderRepositoryInterface $orders)
    {
        $this->orders = $orders;
    }
    
    public function getRecent()
    {
        $recent = $this->orders->getMostRecent(Auth::user());
        return View::make("orders.recent", compact("recent"));
    }
}

前端開(kāi)發(fā)人員可以自己實(shí)現(xiàn)一個(gè)“假”接口,來(lái)測(cè)試應(yīng)用試圖中需要填充的數(shù)據(jù)。

class DummyOrderRepository implements OrderRepositoryInterface 
{
    public function getMostRecent(User $user)
    {
        return array("Order 1", "Order 2", "Order 3");
    }
}

接口實(shí)現(xiàn)之后,我們就能將其綁定到容器中,就能在整個(gè)應(yīng)用中使用他了:

App::bind("OrderRepositoryInterface", "DummyOrderRepository");

當(dāng)后端開(kāi)發(fā)人員實(shí)現(xiàn)了他的模塊,比如:RedisOrderRepository。我們?cè)俅瓮ㄟ^(guò)修改綁定將其應(yīng)用到項(xiàng)目之中。

接口大綱

接口在被用來(lái)定義項(xiàng)目“骨架”上是非常有用的。在項(xiàng)目組件設(shè)計(jì)階段可以促進(jìn)團(tuán)隊(duì)間設(shè)計(jì)討論。比如定義BillingNotifierInterface接口,并討論接口相應(yīng)的方法,在敲代碼前就能用接口定義出一套好的API。

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

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

相關(guān)文章

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

    摘要:然而,我們需要注意的是僅是軟件設(shè)計(jì)模式依賴注入的一種便利的實(shí)現(xiàn)形式。容器本身不是依賴注入的必要條件,在框架他只是讓其變得更加簡(jiǎn)便。首先,讓我們探索下為什么依賴注入是有益的。繼續(xù)深入讓我們通過(guò)另一個(gè)示例來(lái)加深對(duì)依賴注入的理解。 聲明:本文并非博主原創(chuàng),而是來(lái)自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證9...

    sunsmell 評(píng)論0 收藏0
  • Laravel深入學(xué)習(xí)11 - 接口分離原則

    摘要:實(shí)際上,本原則要求接口必須是粒度明確的。當(dāng)你的代碼不符合接口分離原則時(shí),那也肯定違背了單一責(zé)任原則。接口分離原則本原則是指在實(shí)現(xiàn)類(lèi)中對(duì)于接口中的方法并不強(qiáng)制去實(shí)現(xiàn)使用不到的方法。 聲明:本文并非博主原創(chuàng),而是來(lái)自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證90%的原汁性,另外因?yàn)槭抢斫夥g,肯定會(huì)有錯(cuò)誤...

    lwx12525 評(píng)論0 收藏0
  • Laravel深入學(xué)習(xí)2 - 控制反轉(zhuǎn)容器

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

    worldligang 評(píng)論0 收藏0
  • Laravel深入學(xué)習(xí)7 - 框架的擴(kuò)展

    摘要:組件擴(kuò)展通常有兩種方法向容器中綁定自己的接口實(shí)現(xiàn)痛過(guò)使用工廠模式實(shí)現(xiàn)的類(lèi)注冊(cè)自己的擴(kuò)展。類(lèi)庫(kù)管理類(lèi)以工廠模式實(shí)現(xiàn),負(fù)責(zé)諸如緩存等驅(qū)動(dòng)的實(shí)例化。閉包須要傳入繼承自和容器的實(shí)例化對(duì)象。當(dāng)完成擴(kuò)展之后要記住中替換成自己的擴(kuò)展名稱。 聲明:本文并非博主原創(chuàng),而是來(lái)自對(duì)《Laravel 4 From Apprentice to Artisan》閱讀的翻譯和理解,當(dāng)然也不是原汁原味的翻譯,能保證9...

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

    摘要:在改變存儲(chǔ)系統(tǒng)的情況下,必須對(duì)進(jìn)行修改,違背了開(kāi)放封閉原則。傳統(tǒng)的依賴痛過(guò)倒置就能事代碼變得非常靈活,易于改變 聲明:本文并非博主原創(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)注明出處,謝謝! 依賴反轉(zhuǎn)原則 ...

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

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

0條評(píng)論

閱讀需要支付1元查看
<