laravel 基礎(chǔ)教程 —— 契約

契約

簡介

laravel 的契約是對應(yīng)用框架的核心服務(wù)所要求的一種強有力的約束请琳。它本身定義一些接口座云,要求服務(wù)必須要遵守骗污。比如,Illuminate\Contracts\Queue\Queue 契約定義了隊列任務(wù)所必須的方法点骑,而 Illuminate\Contracts\Mail\Mailer 契約定義了一些發(fā)送郵件所必須的方法。

每種契約在框架中都有相應(yīng)的提供者去進(jìn)行實現(xiàn)谍夭。比如黑滴,laravel 提供了多種驅(qū)動的隊列任務(wù)的實現(xiàn),還有其中一個的郵件服務(wù)的實現(xiàn)是由 SwiftMailer 集成的紧索。

所有的 laravel 契約你都可以在這里找到:GitHub袁辈。這里提供了一個對 laravel 契約參考的快速入口,你可以很好的對這些單一解耦的包進(jìn)行獨立實現(xiàn)的開發(fā)齐板。

契約 Vs. 假面(Facades)

laravel 的假面模式提供了一種簡單的方法去從服務(wù)容器中取出服務(wù)而不需要使用類型提示吵瞻。使用契約可以使你明確的定義類間的依賴。而對于大多數(shù)應(yīng)用來說甘磨,使用假面模式就可以了橡羞。但是,如果你想要松耦合易擴(kuò)展的服務(wù)济舆,那么契約可以實現(xiàn)卿泽。

為什么使用契約?

對于契約,你可能會產(chǎn)生很多的疑問签夭。為什么要總是使用接口齐邦?使用接口不是會變的更復(fù)雜嗎?讓我們來提煉一下使用接口的原因:松耦合和簡潔性第租。

松耦合

首先措拇,讓我們來看一下一個緊耦合的關(guān)于緩存的實現(xiàn),請閱讀下面的代碼好好思考一下:

<?php

namespace App\Orders;

class Repository
{
  /**
   * The cache instance.
   */
   protected $cache;

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

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

在上面的類中慎宾,代碼給予了類一個緊耦合的緩存的實現(xiàn)丐吓。之所以說是緊耦合的,是因為它依賴于一個具體的實現(xiàn)類趟据,也就是說它和這個包的供應(yīng)商是緊密耦合的券犁。如果我們需要換一個包的供應(yīng)商,那么我們就要修改我們的代碼汹碱。

同樣的粘衬,如果我們想要切換我們的底層緩存驅(qū)動,從 memcached 切換到 redis咳促,那么我們也必須要修改大量的業(yè)務(wù)代碼稚新。所以,鑒于此跪腹,我們的資料庫不應(yīng)該對所提供的依賴需要知道的太多枷莉,而僅僅需要知道他們提供了我們所需的就可以了(這和鴨子類型的故事有點相似)。

鑒于此尺迂,我們可以采取一種與上述相反的方法來進(jìn)行解耦笤妙。我們提供一個無關(guān)具體實現(xiàn)的接口:

<?php

namespace App\Orders;

use Illuminate\Contracts\Cache\Repository as Cache;

class Respository
{
  /**
   * The cache instance.
   */
   protected $cache;

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

現(xiàn)在上面的代碼并沒有連接到任何的具體實現(xiàn)庫,甚至是 laravel噪裕。因為契約只定義了接口蹲盘,它并不包含任何的依賴和實現(xiàn),所以你可以非常簡單的去實現(xiàn)任何給定的契約膳音,你只需要根據(jù)契約編寫一個不同的實現(xiàn)就可以進(jìn)行輕松的替換召衔。而并不用修改之前寫過的代碼。

簡單

當(dāng)所有的 laravel 的服務(wù)都通過簡單整潔的接口進(jìn)行定義祭陷,那么它就可以被非常輕松的確定所給定服務(wù)具有哪些功能苍凛。這樣也可以說 laravel 的契約服務(wù)其實是已經(jīng)提供了簡潔的功能文檔了。

契約參考

下面是 laravel 契約及其對應(yīng)的假面的參考:

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

怎么使用契約

那么兵志,如何得到一個契約的實現(xiàn)呢醇蝴?其實這相當(dāng)?shù)暮唵巍?/p>

在 laravel 中很多類型的類都是通過服務(wù)容器來獲取的,包括控制器想罕,事件監(jiān)聽器悠栓,中間件,隊列任務(wù),和路由閉包惭适。所以笙瑟,你可以直接通過在構(gòu)造函數(shù)中使用類型提示來構(gòu)造接口依賴,這樣在類被解析時會自動的獲取契約的實例癞志,我們通過一個簡單的例子來看一下:

<?php

namespace App\Listeners;

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

class CacheUserInformation
{
  /**
   * 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 NewUserRegistered $event
     * @return void
     */
     public function handle(NewUserRegistered $event)
     {
        //
     }
}

一旦事件監(jiān)聽器被解析往枷,服務(wù)容器就會讀構(gòu)造函數(shù)中的類型提示,然后根據(jù)類型提示去注入適當(dāng)?shù)膶嵗啾jP(guān)于更多的在服務(wù)容器中進(jìn)行類的綁定注冊师溅,你可以查看服務(wù)容器的文檔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盾舌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蘸鲸,更是在濱河造成了極大的恐慌妖谴,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酌摇,死亡現(xiàn)場離奇詭異膝舅,居然都是意外死亡,警方通過查閱死者的電腦和手機窑多,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門仍稀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人埂息,你說我怎么就攤上這事技潘。” “怎么了千康?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵享幽,是天一觀的道長。 經(jīng)常有香客問我拾弃,道長值桩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任豪椿,我火速辦了婚禮奔坟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘搭盾。我一直安慰自己咳秉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布鸯隅。 她就那樣靜靜地躺著滴某,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上霎奢,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天户誓,我揣著相機與錄音,去河邊找鬼幕侠。 笑死帝美,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的晤硕。 我是一名探鬼主播悼潭,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了碎乃?” 一聲冷哼從身側(cè)響起健提,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎占拍,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捎迫,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡晃酒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了窄绒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贝次。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖彰导,靈堂內(nèi)的尸體忽然破棺而出蛔翅,到底是詐尸還是另有隱情,我是刑警寧澤位谋,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布搁宾,位于F島的核電站,受9級特大地震影響倔幼,放射性物質(zhì)發(fā)生泄漏盖腿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一损同、第九天 我趴在偏房一處隱蔽的房頂上張望翩腐。 院中可真熱鬧,春花似錦膏燃、人聲如沸茂卦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽等龙。三九已至处渣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蛛砰,已是汗流浹背罐栈。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留泥畅,地道東北人荠诬。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像位仁,于是被迫代替她去往敵國和親柑贞。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理聂抢,服務(wù)發(fā)現(xiàn)钧嘶,斷路器,智...
    卡卡羅2017閱讀 134,638評論 18 139
  • 簡介 laravel 使實施認(rèn)證的變得非常簡單琳疏,事實上有决,它提供了非常全面的配置項以適應(yīng)應(yīng)用的業(yè)務(wù)。認(rèn)證的配置文件存...
    Dearmadman閱讀 6,121評論 2 13
  • 原文鏈接 必備品 文檔:Documentation API:API Reference 視頻:Laracasts ...
    layjoy閱讀 8,605評論 0 121
  • 概述 Laravel 的 Contracts 是一組定義了框架核心服務(wù)的接口( interfaces )轿亮。 例如I...
    伊Summer閱讀 2,783評論 0 2
  • 緩存 配置 Laravel 對多種緩存系統(tǒng)提供了統(tǒng)一的 API。緩存的配置文件存放在 config/cache.p...
    Dearmadman閱讀 11,980評論 0 8