契約


コントラクトを使用する場合

各コントラクトには、対応するフレームワークによって提供される実装があります。たとえば、Laravel は複数のドライバー キュー実装を提供し、SwiftMailer を使用して電子メール コントラクトを実装します。 すべての Laravel コントラクトは、

それぞれの GitHub リポジトリ
にあります。これにより、利用可能なすべてのコントラクトのクイック リファレンス エントリと、拡張パッケージ開発者が使用できる単一の分離されたパッケージが提供されます。

コントラクトとファサード

Laravel のファサードとヘルパー関数は、タイプヒントなしで Laravel サービスを使用する簡単な方法を提供し、サービスコンテナの外部でコントラクトを解決することもできます。ほとんどの場合、各ファサードには同等の契約があります。

ファサード (依存関係を参照するためにクラス内のコンストラクターを必要としません) とは異なり、コントラクトを使用すると、クラスの明示的な依存関係を定義できます。依存関係が明確に定義されることを好み、コントラクトを使用することを好む開発者もいますが、ファサードによってもたらされる利便性を享受している開発者もいます。

{ヒント} ほとんどのアプリケーションでは、ファサードとコントラクトのどちらを選択しても問題ありません。ただし、拡張パッケージを構築している場合は、パッケージのコンテキスト内でのテストが容易になるため、コントラクトの使用を強く検討する必要があります。

コントラクトを使用する場合

要約すると、大規模な場合にコントラクトとファサードのどちらを使用するかということになります。範囲は個人またはチームの好みによって異なります。コントラクトとファサードの両方を使用して、堅牢で十分にテストされた Laravel アプリケーションを構築できます。クラスの責任を単純に保つ限り、コントラクトを使用する場合とファサードを使用する場合の実際の違いは非常に小さいことがわかります。

ただし、契約に関してまだ多くの質問があるかもしれません。たとえば、なぜインターフェイスを使用するのですか?インターフェースの使い方がもっと複​​雑ではないでしょうか?その理由を次の内容 (「低結合」と「単純さ」) で抽出してみましょう。

#低結合

まず、キャッシュ実装のための高結合コードをいくつか見てみましょう。次のコードがあるとします。

<?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{  
    /**
     * 缓存实例.
     */    protected $cache;    /**
     * 创建一个新的仓库实例.
     *
     * @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\Factory;
  class CacheOrderInformation{  
    /**
     * Redis 工厂实现。
     */   
     protected $redis;  
   /**
     * 创建一个新的事件处理器实例。
     *
     * @param  Factory  $redis
     * @return void
     */   
     public function __construct(Factory $redis)  
       {     
          $this->redis = $redis;  
        } 
     /**
     * 处理事件。
     *
     * @param  OrderWasPlaced  $event
     * @return void
     */  
    public function handle(OrderWasPlaced $event) 
       {    
           //  
        }
    }

イベント リスナーが解決されると、サービス コンテナはクラスのコンストラクターの型ヒントを読み取り、適切な値を挿入します。 。サービス コンテナへの登録の詳細については、サービス コンテナのドキュメントを確認してください。

契約リファレンス

この表は、すべての Laravel 契約とそれに相当するファサードのクイック リファレンスを提供します。

# #Illuminate\Contracts\Broadcasting\BroadcasterBroadcast::connection()Illuminate\Contracts\Broadcasting\ブロードキャストする必要があります#Illuminate\Contracts\Console \カーネルアーティザン照明\契約\コンテナ\コンテナAppIlluminate\Contracts\Cookie\FactoryCookie#Illuminate\Contracts\Cookie\QueueingFactory ##Illuminate\Contracts\Database\ModelIdentifierIlluminate\Contracts\Debug\ExceptionHandler#Illuminate\Contracts\Encryption\Encrypter ##Illuminate\Contracts\Events\DispatcherIlluminate\Contracts\Filesystem\CloudIlluminate\Contracts\Filesystem\Factory#Illuminate\Contracts\Routing\BindingRegistrarRouteIlluminate\Contracts\Routing\RegistrarRouteIlluminate\Contracts\Routing\ResponseFactoryResponseIlluminate\Contracts\Routing\UrlGeneratorURLIlluminate\Contracts\Routing\UrlRoutableIlluminate\Contracts \Session\SessionSession::driver()Illuminate\Contracts\Support\ArrayableIlluminate\Contracts\Support\Htmlable ##Illuminate\Contracts\Support\JsonableIlluminate\Contracts\Support\MessageBag#Illuminate\Contracts\Support\MessageProviderIlluminate\Contracts\Support \レンダリング可能Illuminate\Contracts\Support\Responsable照明\契約\翻訳\ローダー
契約参照ファサード
Illuminate\Contracts\Auth\Access\承認可能
Illuminate\Contracts\Auth\Access\GateGate
Illuminate\Contracts\Auth\Authenticatable
Illuminate\Contracts\ Auth\CanResetPassword
Illuminate\Contracts\Auth\FactoryAuth
#Illuminate\Contracts\Auth\GuardAuth::guard()
Illuminate\Contracts\Auth\PasswordBrokerPassword::broker()
#Illuminate\Contracts\Auth\PasswordBrokerFactoryPassword
Illuminate\Contracts\Auth\StatefulGuard
Illuminate\Contracts\Auth\SupportsBasicAuth
#Illuminate\Contracts\Auth\UserProvider
Illuminate\Contracts\Bus\DispatcherBus
Illuminate\Contracts\Bus\QueueingDispatcherBus::dispatchToQueue()
Illuminate\Contracts\Broadcasting\FactoryBroadcast
Illuminate\Contracts\Broadcasting\ShouldBroadcastNow
##Illuminate\Contracts\Cache\FactoryCache
Illuminate\Contracts\Cache\Lock
Illuminate\Contracts\Cache\LockProvider
##Illuminate\Contracts\Cache\RepositoryCache::driver()
Illuminate\Contracts\Cache \Store
Illuminate\Contracts\Config\RepositoryConfig
#Illuminate\Contracts\Console\Application
Cookie::queue()
Crypt
イベント
Storage::cloud()
ストレージ
Illuminate\Contracts\Filesystem\Filesystemストレージ::ディスク()
Illuminate\Contracts\Foundation\ApplicationApp
Illuminate\Contracts\Hashing\Hasherハッシュ
Illuminate\Contracts \Http\Kernel
Illuminate\Contracts\Mail\MailQueueMail:: queue()
Illuminate\Contracts\Mail\Mailable
##Illuminate\Contracts\Mail\MailerMail
Illuminate\Contracts\Notifications\Dispatcher 通知
Illuminate\Contracts\Notifications\Factory通知
Illuminate\Contracts\Pagination\LengthAwarePaginator
Illuminate\Contracts \Pagination\Paginator
Illuminate\Contracts\Pipeline\Hub
Illuminate\Contracts\Pipeline\Pipeline
Illuminate\Contracts\Queue\EntityResolver
Illuminate\Contracts\Queue\Factoryキュー
Illuminate\Contracts\Queue\Job
Illuminate\Contracts\Queue\Monitor キュー
Illuminate\Contracts\Queue\QueueQueue::connection()
Illuminate\Contracts\Queue\QueueableCollection
#Illuminate\Contracts\Queue\QueueableEntity
Illuminate\Contracts\Queue \ShouldQueue
Illuminate\Contracts\Redis\FactoryRedis
Illuminate\Contracts\Translation\TranslatorLang
Illuminate\Contracts\Validation\FactoryValidator
Illuminate\Contracts \Validation\ImplicitRule
Illuminate\Contracts\Validation\Rule
Illuminate\Contracts\Validation\ValidatesWhenResolved
Illuminate\Contracts\Validation\Validator Validator::make()
Illuminate\Contracts\View\Engine
#Illuminate\Contracts\View\FactoryView
Illuminate\Contracts\View\ViewView::make()
本文文章首掲載