Laravel 5におけるcontracctsの詳細
まず、公式文書のcontractsの定義を見てみます。
Laravel's Contracts art a set of interfaces that define the coree services provided by the frame ework.
LaravelのContractsは、フレームワークによって提供されるコアサービスインターフェースを定義した集合という意味です。
つまり、各Contractは一つのインターフェースであり、一つのフレームのコアサービスに対応しています。
その意味は何ですか?公式サイトの説明も簡単です。インタフェースを使うのは松結合と簡単なためです。
大道理はともかく、まず乾物を注文して、どうやって利用しますか?
まずcontractsインターフェースのリストをご覧ください。
まず、アプリ/Providers/AppServiceProvider.phpを開いて、registerの方法に注意します。
注意してください。Illuminate\Contracts\Auth\Registarはcontractです。アプリ\Services\Registarというファイルは、ap/Services/Registar.phpにあります。
続いてApp\Http\Controller\Auth\AuthControllerというコントローラ類を見ます。constructコンストラクタ:
全体の使用プロセスは実は二つのステップにまとめることができます。
contractインターフェースを実現する対象を容器に登録する。
コンストラクタパラメータの種類はcontractインターフェースクラスに指定されています。フレームは自動的に条件に合うオブジェクトを見つけます。
では、アウトレットのメリットについて説明します。
松の結合
公式サイトでは、タイトカップリングやContractインターフェースがなぜ結合を緩めるかを説明する例をあげています。
まず、結合コードを見てみましょう。
では、Contractインターフェースはどうやってこの問題を解決しますか?コードを見てください:
単純性
すべてのサービスがインターフェースを使って定義すれば、サービスに必要な機能を簡単に決定でき、よりメンテナンスと拡張がしやすくなり、また、contractインターフェースは簡潔な文書として読みやすいです。
Laravel's Contracts art a set of interfaces that define the coree services provided by the frame ework.
LaravelのContractsは、フレームワークによって提供されるコアサービスインターフェースを定義した集合という意味です。
つまり、各Contractは一つのインターフェースであり、一つのフレームのコアサービスに対応しています。
その意味は何ですか?公式サイトの説明も簡単です。インタフェースを使うのは松結合と簡単なためです。
大道理はともかく、まず乾物を注文して、どうやって利用しますか?
まずcontractsインターフェースのリストをご覧ください。
Illuminate\Contracts\Auth\Guard
Illuminate\Contracts\Auth\PasswordBroker
Illuminate\Contracts\Bus\Dispatcher
Illuminate\Contracts\Cache\Repository
Illuminate\Contracts\Cache\Factory
Illuminate\Contracts\Config\Repository
Illuminate\Contracts\Container\Container
Illuminate\Contracts\Cookie\Factory
Illuminate\Contracts\Cookie\QueueingFactory
Illuminate\Contracts\Encryption\Encrypter
Illuminate\Contracts\Routing\Registrar
…多すぎます。続けて貼るのがおっくうです。公式サイトのマニュアルにあります。Illuminate\Contracts\Routing\Registarというcontractを見せてみましょう。まず、アプリ/Providers/AppServiceProvider.phpを開いて、registerの方法に注意します。
public function register()
{
$this->app->bind(
'Illuminate\Contracts\Auth\Registrar',
'App\Services\Registrar'
);
}
$this->appは、Applicationオブジェクトであり、コンテナオブジェクトでもあります。注意してください。Illuminate\Contracts\Auth\Registarはcontractです。アプリ\Services\Registarというファイルは、ap/Services/Registar.phpにあります。
続いてApp\Http\Controller\Auth\AuthControllerというコントローラ類を見ます。constructコンストラクタ:
public function __construct(Guard $auth, Registrar $registrar)
{
$this->auth = $auth;
$this->registrar = $registrar;
$this->middleware('guest', ['except' => 'getLogout']);
}
二つのパラメータがあります。対応するクラスの名前空間はスクリプトの先頭にあります。
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\Registrar;
これらは全部contractですが、ここでRegistarを持って言います。この中にはパラメータタイプで$registarのインターフェースタイプを指定しただけです。実際に呼び出した時は実際にApp\Services\Registarという種類があります。これは注入の特性に依存しています。Laravelは自動的に容器の中を検索してインターフェースIlluminate\Contracts\Auth\Registarの種類や対象を実現します。ある場合は実際のパラメータとして構造関数に伝えられます。全体の使用プロセスは実は二つのステップにまとめることができます。
contractインターフェースを実現する対象を容器に登録する。
コンストラクタパラメータの種類はcontractインターフェースクラスに指定されています。フレームは自動的に条件に合うオブジェクトを見つけます。
では、アウトレットのメリットについて説明します。
松の結合
公式サイトでは、タイトカップリングやContractインターフェースがなぜ結合を緩めるかを説明する例をあげています。
まず、結合コードを見てみましょう。
<?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))
{
//
}
}
}
構築関数には、詳細なキャッシュの実装\SomePackage\Cache\Memcachedを注入しているのが見えますが、Redisをキャッシュサーバとしたり、api方法を変更したりすれば、修正が必要です。プロジェクトが大きいと、どのぐらい修正が必要なのか分かりません。では、Contractインターフェースはどうやってこの問題を解決しますか?コードを見てください:
<?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;
}
}
注意してください。キャッシュは私たちがインターフェースを使っています。つまり、contract、Illuminate\Contracts\Cache\Repositoryを使っています。これはインターフェースだけなので、後ろにあるmemcacheに関心を持つ必要はありません。単純性
すべてのサービスがインターフェースを使って定義すれば、サービスに必要な機能を簡単に決定でき、よりメンテナンスと拡張がしやすくなり、また、contractインターフェースは簡潔な文書として読みやすいです。