1

私のアプリケーションでは、ユーザーは 3 種類のライセンスにサインアップできます。すべての人が利用できる無料のライセンス、支払いが必要なサブスクリプション ライセンス (外部の当事者によって管理されます)、および請求書がライセンスされているため、私たちに連絡する必要があります。 .

ユーザーは、登録時または後でプロファイルからライセンスを選択できます。これらは、異なるメソッドを持つ 2 つの異なるコントローラーです。

User と License エンティティを受け取り、ユーザーが正しいライセンスにサインアップするすべてのロジックを処理するsubscription.managerサービス メソッドがあります。subscribe(User $user, License $license)

ユーザーが選択したライセンスに基づいて、結果は異なります。

  • 無料を選択した場合は、お礼のページにリダイレクトされます
  • 請求書を選択すると、請求書を要求したことを確認するページにリダイレクトされます。
  • サブスクリプションを選択した場合、最初に支払いページにリダイレクトする必要があります。

最後のオプションは単純RedirectResponseですが、既存のライセンス サブスクリプションを登録したのか、単に変更したのかに基づいて、さまざまなページを表示したいと考えています。

これを処理する最良の方法は何ですか?

現時点では、私はこれを行います:

$response = $this->get('subscription.manager')->subscribe($user, $license);

switch (true) {
    case $response instanceof SuccessResponse:
        return $this->redirect('success_url');
    break;
    case $response instanceof RequestedResponse;
        return $this->redirect('requested_url');
    break;
    case $response instanceof RedirectResponse:
        return $response;
    break;
    default:
        throw new \Exception('Response not recognized');
}

SuccessResponseRequestedResponseは、私が作成した単純なクラスであり、それ自体はほとんどまたはまったく情報を保持していません。メソッドで何が起こったかを純粋に示しています。

これにより、このブロックをコピーして貼り付けるだけで、成功した URL と要求された URL を切り替えることができます。ただし、これはあまり最適ではないように感じます。これを行うより良い方法はありますか?

成功と要求された応答 (Redirect または Render のいずれか) を作成し、それらをサービス メソッドに渡すことができると思います。しかし、それは私が単一責任の原則に違反しているように感じます.

4

1 に答える 1

1

サブスクリプション マネージャーは、リダイレクトなどにまったく関心を持つべきではないと思います。したがって、最初のステップとして、次のようにします。

$result = $this->get('subscription.manager')->subscribe($user, $license);

switch ($result) {
    case 'ProcessedFreeLicense':
        return $this->redirect('success_url');
    break;
    case 'ProcessedInvoicedLicense';
        return $this->redirect('requested_url');
    break;
    case 'ProcessedSubstrictionLicense':
        return $response;
    break;
    default:
        throw new \Exception('Response not recognized');
}

それでも、コントローラーに switch ステートメントといくつかの繰り返しコードが残ります。switch ステートメントを基本コントローラー クラスに移動できます。

ただし、ProcessedLicense イベントをディスパッチしてから、リスナーにライセンスの種類ごとに何をするかを決定させることを検討します。実際の例として FOSUserBundle.RegistrationController の開発バージョンを見てください。ただし、基本的には次のとおりです。

$result = $this->get('subscription.manager')->subscribe($user, $license);
$event = new ProcessedLicenseEvent($user,$license,$results);
$dispatcher->dispatch(LicenseEvents::PROCESSED_LICENSE, $event);
return $event->getResponse();

そのため、ライセンスの処理後に何をすべきかに関連するすべてのロジックは、1 つまたは複数のリスナー内に収めることができます。コントローラーに影響を与えることなく、必要に応じて変更できます。

================================================== ===================

完全を期すために3番目のアプローチを追加すると思いました。このアプローチは、一部の C#/Java ベースのアプリケーションでは非常に一般的です。これは、コマンドが値を返さず、コントローラーが値を期待しない「ファイア アンド フォーゲット」アプローチです。

// This is the Command.  It does not return a value.
$this->get('subscription.manager')->subscribe($user, $license);

// Always just go here
return $this->redirect('user_license_status_page');

値を返す必要がなくなったため、コマンド オブジェクトが単純化されたことは明らかです。また、共有の switch ステートメントを削除しました。licence_status コントローラーは、何が起こったかをユーザーに表示し、必要に応じてさらにアクションを実行できます。

于 2013-08-27T14:33:31.080 に答える