0

Spring MVC に基づいて、DDD の概念を中心に編成された Web アプリケーションを実装しています。現在、チケット予約機能を実装しようとしています。顧客は、特定のイベントで利用可能なチケットの数を確認できます。次に、予約するチケットの数を入力し、フォームを送信できます。要求は、登録を担当するアプリケーション サービスを呼び出すコントローラーによって受信されます。アプリケーション サービスのロジックは次のとおりです。

  1. 受信パラメーターを検証します。
    • 1A。指定された ID のイベントが存在するかどうかを確認します
    • 1B. 利用可能なチケットの数が予約できるかどうかを確認します
  2. 検証に合格した場合は、登録に進みます。それ以外の場合は、エラーを報告してください。

検証エラーを報告する適切な方法について、特にポイント 1B について疑問があります。チケットの数が予約を許可しない状況は、非常に珍しいことではありません。顧客は、データベース内の現在のチケット数と完全に同期されていないチケットの数を確認できます (結果整合性)。その間に、他の人がいくつかのチケットを予約できます。

最初は、いくつかの特定の例外をスローして、この問題を報告することを考えていました。ただし、他にも問題のある状況がいくつか考えられますが、それぞれに 1 つの例外を設けるのはあまり良くないように思えます。

私が検討していたもう 1 つのオプションは、エラー コードを含む 1 種類の例外をスローすることでした。しかし、Spring MVC でこの状況を適切に処理する方法がわかりません。

このような問題のベストプラクティスは何ですか? MVC アプリケーションでそれらをどのように処理しますか? アドバイスをいただければ幸いです。

4

1 に答える 1

1

これらは取り返しのつかないビジネス制約の破れだと思います。

私の現在の解決策は例外階層です。

public abstract class UncheckedApplicationException extends RuntimeException {

    //omitted factory methods and constructors
    public abstract String getStatusCode();

    public abstract String getI18nCode();//ignore this if you don't need i18n    

    public abstract String[] getI18nArgs();//ignore this if you don't need i18n 
}

カスタム例外は、これを拡張します。これにより、次のようなコードを回避できると思います。

try {  
    //invoke your application service
} catch (InsufficientInventoryException e) {  
    statusCode = INSUFFICIENT_INVENTORY;  
} catch (ExpriedPriceException e) {  
    statusCode = EXPIRED_PRICE;  
} catch (NoSuchProductException e) {  
    statusCode = NO_SUCH_PRODUCT;  
} catch (Exception e) {  
    statusCode = UNKNOWN;  
}

コントローラーのコード スニペット:

try {  
    //invoke your application service here 
    statusCode = SUCCESS;
    message = messageSource.getSuccess(locale));
} catch (UncheckedApplicationException e) {  
    statusCode = e.getStatusCode();  
    message = messageSource.getMessage(e, locale));
} catch (Exception e) {  
    statusCode = UNKNOWN;  
    message = messageSource.getUnknownError(e, locale));
}
//add statusCode & message to modelAttribute

コントローラーが適切に構成されている場合は、 @ExceptionHandler を使用してボイラープレートの try-catch コードを減らすことができます (ただし、かなり困難です)。

Exceptionon を使用するもう 1 つの理由は、トランザクション境界を区切るためにアプリケーション サービスがよく使用されることです。ロールバックする場合は、例外をスローする必要があります。

于 2013-08-06T01:01:35.613 に答える