鍍金池/ 教程/ PHP/ Contracts
Laravel Cashier
Eloquent ORM
HTTP 響應(yīng)
發(fā)行說明
擴(kuò)展包開發(fā)
HTTP 控制器
事件
擴(kuò)展框架
Contracts
開發(fā)
配置
表單驗(yàn)證
錯誤與日志
Hashing
貢獻(xiàn)指南
郵件
Session
遷移與數(shù)據(jù)填充
查詢構(gòu)造器
Redis
升級向?qū)?/span>
概覽
緩存
服務(wù)提供者
Envoy 任務(wù)執(zhí)行器
隊(duì)列
單元測試
服務(wù)容器
文件系統(tǒng) / 云存儲
認(rèn)證
請求的生命周期
加密
模板
視圖 (View)
Laravel Homestead
Laravel 安裝指南
介紹
Command Bus
分頁
輔助方法
應(yīng)用程序結(jié)構(gòu)
HTTP 路由
HTTP 請求
基本用法
本地化
HTTP 中間件
結(jié)構(gòu)生成器
Facades
Laravel Elixir

Contracts

簡介

Laravel 的 Contracts 是一組定義了框架核心服務(wù)的接口( interfaces )。例如,Queue contract 定義了隊(duì)列任務(wù)所需要的方法,而 Mailer contract 定義了發(fā)送 e-mail 需要的方法。

在 Laravel 框架里,每個(gè) contract 都提供了一個(gè)對應(yīng)的實(shí)現(xiàn)。例如, Laravel 提供了有多種驅(qū)動的 Queue 的實(shí)現(xiàn),而根據(jù) SwiftMailer 實(shí)現(xiàn)了 Mailer。

Laravel 所有的 contracts 都放在各自的 Github repository。除了提供了所有可用的 contracts 一個(gè)快速的參考,也可以單獨(dú)作為一個(gè)低耦合的擴(kuò)展包讓其他擴(kuò)展包開發(fā)者使用。

為什么用 Contracts?

你可能有很多關(guān)于 contracts 的問題。如為什么要使用接口?使用接口會不會變的更復(fù)雜?

讓我們用下面的標(biāo)題來解釋為什么要使用接口:低耦合和簡單性。

低耦合

首先,看一些強(qiáng)耦合的緩存實(shí)現(xiàn)代碼。如下:

<?php namespace App\Orders;

class Repository {

    /**
     * The cache.
     */
    protected $cache;

    /**
     * Create a new repository instance.
     *
     * @param  \SomePackage\Cache\Memcached  $cache
     * @return void
     */
    public function __construct(\SomePackage\Cache\Memcached $cache)
    {
        $this->cache = $cache;
    }

    /**
     * Retrieve an Order by ID.
     *
     * @param  int  $id
     * @return Order
     */
    public function find($id)
    {
        if ($this->cache->has($id))
        {
            //
        }
    }

}

在上面的類里,代碼跟緩存實(shí)現(xiàn)之間是強(qiáng)耦合。理由是它會依賴于擴(kuò)展包庫( package vendor )的特定緩存類。一旦這個(gè)擴(kuò)展包的 API 更改了,我們的代碼也要跟著改變。

同樣的,如果想要將底層的緩存技術(shù)(比如 Memcached )抽換成另一種(像 Redis ),又一次的我們必須修改這個(gè) repository 類。我們的 repository 不應(yīng)該知道這么多關(guān)于誰提供了數(shù)據(jù),或是如何提供等等細(xì)節(jié)。

比起上面的做法,我們可以改用一個(gè)簡單、和擴(kuò)展包無關(guān)的接口來改進(jìn)代碼:

<?php namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class Repository {

    /**
     * Create a new repository instance.
     *
     * @param  Cache  $cache
     * @return void
     */
    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }

}

現(xiàn)在上面的代碼沒有跟任何擴(kuò)展包耦合,甚至是 Laravel。既然 contracts 擴(kuò)展包沒有包含實(shí)現(xiàn)和任何依賴,你可以很簡單的對任何 contract 進(jìn)行實(shí)現(xiàn),你可以很簡單的寫一個(gè)替換的實(shí)現(xiàn),甚至是替換 contracts,讓你可以替換緩存實(shí)現(xiàn)而不用修改任何用到緩存的代碼。

簡單性

當(dāng)所有的 Laravel 服務(wù)都簡潔的使用簡單的接口定義,就能夠很簡單的決定一個(gè)服務(wù)需要提供的功能。可以將 contracts 視為說明框架特色的簡潔文檔.

除此之外,當(dāng)你依賴簡潔的接口,你的代碼能夠很簡單的被了解和維護(hù)。比起搜索一個(gè)大型復(fù)雜的類里有哪些可用的方法,你有一個(gè)簡單,干凈的接口可以參考。

Contract 參考

以下是大部分 Laravel Contracts 的參考,以及相對應(yīng)的 "facade"

Contract Laravel 4.x Facade
IlluminateContractsAuthGuard Auth
IlluminateContractsAuthPasswordBroker Password
IlluminateContractsBusDispatcher Bus
IlluminateContractsCacheRepository Cache
IlluminateContractsCacheFactory Cache::driver()
IlluminateContractsConfigRepository Config
IlluminateContractsContainerContainer App
IlluminateContractsCookieFactory Cookie
IlluminateContractsCookieQueueingFactory Cookie::queue()
IlluminateContractsEncryptionEncrypter Crypt
IlluminateContractsEventsDispatcher Event
IlluminateContractsFilesystemCloud
IlluminateContractsFilesystemFactory File
IlluminateContractsFilesystemFilesystem File
IlluminateContractsFoundationApplication App
IlluminateContractsHashingHasher Hash
IlluminateContractsLoggingLog Log
IlluminateContractsMailMailQueue Mail::queue()
IlluminateContractsMailMailer Mail
IlluminateContractsQueueFactory Queue::driver()
IlluminateContractsQueueQueue Queue
IlluminateContractsRedisDatabase Redis
IlluminateContractsRoutingRegistrar Route
IlluminateContractsRoutingResponseFactory Response
IlluminateContractsRoutingUrlGenerator URL
IlluminateContractsSupportArrayable
IlluminateContractsSupportJsonable
IlluminateContractsSupportRenderable
IlluminateContractsValidationFactory Validator::make()
IlluminateContractsValidationValidator
IlluminateContractsViewFactory View::make()
IlluminateContractsViewView

如何使用 Contracts

所以,要如何實(shí)現(xiàn)一個(gè) contract?實(shí)際上非常的簡單。很多 Laravel 的類都是經(jīng)由 service container 解析,包含控制器,事件監(jiān)聽,過濾器,隊(duì)列任務(wù),甚至是閉包。所以,要實(shí)現(xiàn)一個(gè) contract,你可以在類的構(gòu)造器使用「類型提示」解析類。例如,看下面的事件處理程序:

<?php namespace App\Handlers\Events;

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

class CacheUserInformation {

    /**
     * Redis 數(shù)據(jù)庫實(shí)現(xiàn)
     */
    protected $redis;

    /**
     * 建立新的事件處理實(shí)例
     *
     * @param  Database  $redis
     * @return void
     */
    public function __construct(Database $redis)
    {
        $this->redis = $redis;
    }

    /**
     * 處理事件
     *
     * @param  NewUserRegistered  $event
     * @return void
     */
    public function handle(NewUserRegistered $event)
    {
        //
    }

}

當(dāng)事件監(jiān)聽被解析時(shí),服務(wù)容器會經(jīng)由類構(gòu)造器參數(shù)的類型提示,注入適當(dāng)?shù)闹?。要知道怎么注冊更多服?wù)容器,參考這個(gè)文檔