web-dev-qa-db-ja.com

Laravelパターン-ジョブとサービスの使用法

ほとんどの開発者がこの2つのLaravelツールをどのように使用するかを考えていました。

Laravelでは、ビジネスロジックをサービスまたはジョブで処理できます(キューに入れられないジョブ、同じプロセスで実行されるジョブについてのみ話しましょう)。

たとえば、ユーザーがエンティティ(ブックなど)を作成する場合、エンティティの作成をサービスまたはジョブのディスパッチで処理できます。

ジョブの使用これは次のようなものです。

class PostBook extends Job
{
    ...
    public function handle(Book $bookEntity)
    {
        // Business logic here.
    }
    ...
}

class BooksController extends Controller
{
    public function store(Request $request)
    {
        ...
        dispatch(new PostBook($request->all()));
        ...
    }
}

サービスの使用、次のようなものになります:

class BookService
{
    public function store(Request $request)
    {
        // Business logic here.
    }
}

class BooksController extends Controller
{
    public function store(Request $request)
    {
        ...
        // I could inject the service instead.
        $bookService = $this->app()->make(App\Services\BookService::class);
        $bookService->store($request);
        ...
    }
}

問題は、主にどのように一方を使用するか、もう一方を使用するかそして、なぜですか?

確かにこの問題には「学校」が2つありますが、それぞれの長所と短所を理解したいと思います。

9

「ビジネスロジック」はanythingで処理できるため、同じビジネスロジック繰り返しコードなし

Jobクラスは、handle()メソッドで定義されているように、通常1つのことを実行します。キューに入れられたジョブを同期して実行すると、通常、低速、高コスト、または信頼性の低いアクション(Web APIの呼び出しなど)を処理するという目的が無効になるため、比較から除外することは困難ですafter現在の要求が完了し、ユーザーに応答が表示されました。

すべてのジョブが同期的であると予想される場合、ビジネスロジックの関数を定義することと大差ありません。これは実際には、同期ジョブのディスパッチが行うことと非常に似ています。コールスタックのどこかでcall_user_func([$job, 'handle'])を実行して、ジョブオブジェクトの単一のメソッドを呼び出します。さらに重要なことに、同期ジョブには再試行のメカニズムがありませんネットワーク障害などの外部の原因により失敗した可能性のあるジョブ。

Servicesは、componentの周りのロジックをカプセル化する簡単な方法です。 1つ以上。この文脈では、コンポーネントは、それを使用していたコードを変更する必要なく、別の実装に交換できるアプリケーションの一部と考えることができます。フレームワークに含まれる完璧な例は、Filesystemサービスです(最も一般的にはStorageファサードでアクセスされます)。

書籍をデータベースに挿入するのではなく、外部APIに投稿することで保存したかどうかを検討します。 BookRepositoryserviceがあり、store()メソッドだけでなく、get()もある場合があります。 update()list()delete()、または他の任意の数のメソッド。これらのリクエストはすべて、外部Webサービスへの認証ロジック(リクエストへのヘッダーの追加など)を共有し、BookRepositoryクラスはその再利用可能なロジックをカプセル化できます。このサービスクラスは、スケジュールされたアーティザンコマンド、Webコントローラー、APIコントローラー、ジョブ、ミドルウェアなどの中でコードを繰り返すことなく使用できます。

この例を使用すると、新しい本を保存するためのJobを作成して、API応答が遅いときにユーザーを待たせないようにすることができます(失敗した場合は再試行してください)。内部的には、ジョブは実行時にService'sstore()メソッドを呼び出します。サービスによって行われる作業は、ジョブによってスケジュールされます。

10
Travis Britz