核心概念 —— 契約(Contracts)

 

一、簡介

Laravel中的契約是指框架提供的一系列定義核心服務的接口。 例如 ,Illuminate\Contracts\Queue\Queue契約定義了隊列任務須要實現的方法,Illuminate\Contracts\Mail\Mailer契約定義了發送郵件所須要實現的方法。 php

每個契約都有框架提供的相應實現。例如,Laravel爲隊列提供了多個驅動的實現,郵件則由 SwiftMailer驅動 實現 。 html

全部Laravel契約都有其對應的GitHub庫,這爲全部有效的契約提供了快速入門指南,同時也能夠做爲獨立、解耦的包被包開發者使用。 laravel

契約(Contracts) VS 門面(Facades)

Laravel門面爲Laravel服務的使用提供了便捷方式——再也不須要從服務容器中類型提示和契約 解析便可直接經過靜態門面調用 。有些開發者喜歡這種便捷,不過也有開發者傾向於使用契約,他們喜歡定義明確的依賴。 git

注:大多數應用中,無論你使用門面仍是契約,合適就好。不過,若是你是在構建一個擴展包,那麼就應該使用契約,由於這在擴展包中更容易測試。github

二、什麼時候使用契約

正如上面所討論的,大多數狀況下使用契約仍是門面取決於我的或團隊的喜愛,契約和門面均可以用於建立強大的、測試友好的Laravel應用。只要你保持類的職責單一,你會發現使用契約和門面並無什麼實質性的差異。 redis

可是,對契約你可能仍是有些疑問。例如,爲何要所有使用接口?使用接口是否是更復雜?下面讓咱們從兩個方面來扒一扒爲何使用接口:鬆耦合和簡單。 swift

鬆耦合

首先,讓咱們看看一些緩存實現的緊耦合代碼:緩存

<?php

namespace App\Orders;

class Repository{
    /**
     * 緩存
     */
    protected $cache;

    /**
     * 建立一個新的Repository實例
     *
     * @param  \SomePackage\Cache\Memcached  $cache
     * @return void
     */
    public function __construct(\SomePackage\Cache\Memcached $cache)
    {
        $this->cache = $cache;
    }

    /**
     * 經過ID獲取訂單
     *
     * @param  int  $id
     * @return Order
     */
    public function find($id)
    {
        if ($this->cache->has($id))    {
            //
        }
    }
}

在這個類中,代碼和給定緩存實現緊密耦合,因爲咱們基於一個來自包的具體的緩存類,若是包的API變了,那麼相應的,咱們的代碼必須作修改。 閉包

相似的,若是咱們想要替換底層的緩存技術(Memcached)爲別的技術實現(Redis),咱們將再一次不得不修改咱們的代碼庫。咱們的代碼庫應該並不知道誰提供的數據或者數據是怎麼提供的。 框架

咱們能夠基於一種簡單的、與提供者無關的接口來優化咱們的代碼,從而替代上述那種實現:

<?php

namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class Repository{
    /**
     * 建立一個新的Repository實例
     *
     * @param  Cache  $cache
     * @return void
     */
    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }
}

如今代碼就不與任何特定提供者耦合,甚至與Laravel都是無關的。因爲契約包不包含任何實現和依賴,你能夠輕鬆的爲給定契約編寫可選實現代碼,你能夠隨意替換緩存實現而不用去修改任何緩存消費代碼。

簡單

當全部Laravel服務都統一在簡單接口中定義,很容易判斷給定服務提供的功能。契約能夠充當框架特性的簡明文檔

此外,基於簡單接口,代碼也更容易理解和維護。在一個龐大而複雜的類中,與其追蹤哪些方法是有效的,不如轉向簡單、乾淨的接口。

三、如何使用契約

那麼,如何實現契約呢?這很簡單。

Laravel中不少類都是經過服務容器進行解析,包括控制器,以及監聽器、中間件、隊列任務,甚至路由閉包。因此,要實現一個契約,須要在解析類的構造函數中類型提示這個契約接口。

例如,看看下面這個事件監聽器:

<?php

namespace App\Listeners;

use App\User;
use App\Events\OrderWasPlaced;
use Illuminate\Contracts\Redis\Database;

class CacheOrderInformation
{
    /**
     * The Redis database implementation.
     */
    protected $redis;

    /**
     * Create a new event handler instance.
     *
     * @param  Database  $redis
     * @return void
     */
    public function __construct(Database $redis)
    {
        $this->redis = $redis;
    }

    /**
     * Handle the event.
     *
     * @param  OrderWasPlaced  $event
     * @return void
     */
    public function handle(OrderWasPlaced $event)
    {
        //
    }
}

事件監聽器被解析的時候,服務容器會讀取構造函數中的類型提示,並注入適當的值。要學習更多關於服務容器的註冊細節,參考其文檔。

四、契約列表

下面是Laravel契約列表,以及其對應的「門面」:

Contract
References Facade

Illuminate\Contracts\Auth\Factory
Auth

Illuminate\Contracts\Auth\PasswordBroker
Password

Illuminate\Contracts\Bus\Dispatcher
Bus

Illuminate\Contracts\Broadcasting\Broadcaster

Illuminate\Contracts\Cache\Repository
Cache

Illuminate\Contracts\Cache\Factory
Cache::driver()

Illuminate\Contracts\Config\Repository
Config

Illuminate\Contracts\Container\Container
App

Illuminate\Contracts\Cookie\Factory
Cookie

Illuminate\Contracts\Cookie\QueueingFactory
Cookie::queue()

Illuminate\Contracts\Encryption\Encrypter
Crypt

Illuminate\Contracts\Events\Dispatcher
Event

Illuminate\Contracts\Filesystem\Cloud

Illuminate\Contracts\Filesystem\Factory
File

Illuminate\Contracts\Filesystem\Filesystem
File

Illuminate\Contracts\Foundation\Application
App

Illuminate\Contracts\Hashing\Hasher
Hash

Illuminate\Contracts\Logging\Log
Log

Illuminate\Contracts\Mail\MailQueue
Mail::queue()

Illuminate\Contracts\Mail\Mailer
Mail

Illuminate\Contracts\Queue\Factory
Queue::driver()

Illuminate\Contracts\Queue\Queue
Queue

Illuminate\Contracts\Redis\Database
Redis

Illuminate\Contracts\Routing\Registrar
Route

Illuminate\Contracts\Routing\ResponseFactory
Response

Illuminate\Contracts\Routing\UrlGenerator
URL

Illuminate\Contracts\Support\Arrayable

Illuminate\Contracts\Support\Jsonable

Illuminate\Contracts\Support\Renderable

Illuminate\Contracts\Validation\Factory
Validator::make()

Illuminate\Contracts\Validation\Validator

Illuminate\Contracts\View\Factory
View::make()

Illuminate\Contracts\View\View

相關文章
相關標籤/搜索