Laravel 5.0 契約

イントロダクション

Laravelの契約はインターフェイスで、フレームワークにより提供されているコアサービスを定義したものです。例えばQueue契約は、ジョブをキューするために必要なメソッドを定義しており、一方、Mailer契約はメール送信に必要なメソッドを定義しています。

それぞれの契約は、フレームワークにより提供されている実装と対応しています。例えば、LaravelはQueueの実装は、多様なドライバーを使用しており、Mailerの実装は、SwiftMailerにより動作しています。

Laravelの全契約は、GitHubのリポジトリーで参照できます。これは全契約を素早く参照する方法であり、同時に他のパッケージ開発者にとっては、個別に独立したパッケージを利用する参考にできるでしょう。

なぜ契約?

契約については皆さん多くの質問をお持ちでしょう。なぜ、インターフェイスを使うんだ?インターフェイスを使えば、もっと複雑になるんじゃないか?

インターフェイスを利用する理由を突き詰めれば、次の2つになります。緩い結合と、単純さです。

緩い結合

最初にキャッシュの実装とがっちり結合したコードをレビューしてみましょう。次のコードをご覧ください。

<?php namespace App\Orders;

class Repository {

    /**
     * キャッシュ
     */
    protected $cache;

    /**
     * 新しいリポジトリーインスタンスの生成
     *
     * @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 {

    /**
     * 新しいリポジトリーインスタンスの生成
     *
     * @param  Cache  $cache
     * @return void
     */
    public function __construct(Cache $cache)
    {
        $this->cache = $cache;
    }

}

これでコードは特定のベンダー、しかもLaravelにさえ依存しなくなりました。契約パッケージは実装も依存も含んでいないため、与えられた契約の異なった実装を簡単に記述できます。キャッシュを使用するコードを変更することなく、キャッシュ実装を置き換えることができるようになりました。

単純さ

Laravelのサービスは全部、シンプルなインターフェイスの中で適切に定義されているので、サービスが提供する機能も簡単に定義できています。 契約はフレームワークの機能の簡単なドキュメントとして使えます。

それに加え、シンプルなインターフェイスに基づけば、あなたのコードは簡単に理解でき、メンテナンスできるようにもなります。大きくて複雑なクラスの中で、どのメソッドが使用可能かを探し求めるよりも、シンプルでクリーンなインターフェイスを参照できます。

契約リファレンス

Laravelのほぼ全ての契約と、Laravelファサードとの比較一覧です。

契約 Laravel 5.x ファサード
Illuminate\Contracts\Auth\Guard Auth
Illuminate\Contracts\Auth\PasswordBroker Password
Illuminate\Contracts\Bus\Dispatcher Bus
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  

契約使用法

では、契約の実装はどうやって入手するのでしょうか?とてもシンプルです。Laravelでは多くのタイプのクラスがサービスコンテナを利用して依存解決されています。コントローラーを始め、イベントリスナー、フィルター、キュージョブ、それにルートクロージャーもそうです。契約の実装を手に入れるには、依存を解決するクラスのコンストラクターで、「タイプヒント」を指定するだけです。例として、次のイベントハンドラーをご覧ください。

<?php namespace App\Handlers\Events;

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

class CacheUserInformation {

    /**
     * Redisデータベースの実装
     */
    protected $redis;

    /**
     * 新しいイベントリスナーインスタンスの生成
     *
     * @param  Database  $redis
     * @return void
     */
    public function __construct(Database $redis)
    {
        $this->redis = $redis;
    }

    /**
     * イベントの処理
     *
     * @param  NewUserRegistered  $event
     * @return void
     */
    public function handle(NewUserRegistered $event)
    {
        //
    }

}

イベントリスナーの依存解決時に、サービスコンテナはクラスのコンストラクターで指定されているタイプヒントを読み取り、適切な値を注入します。サービスコンテナへ何かを登録する方法を学ぶには、ドキュメントを参照してください。

ドキュメント章別ページ

Artisan CLI

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる