3

メソッドの次の設計に困惑しています。

Map<String, BigDecimal> foo(Parameter p){ ... }

このメソッドは複合体を取り、Parameterマップ名 -> 値を返します。多くの場合、パラメータの特定の基礎となる値に基づいて、結果のマップは同じになります。さらに、返される可能性のある異なるマップはわずかしかないため、これらはキャッシュされます。ただし、マップが最初に作成されたときは、さまざまな種類のエラーが発生する可能性があります。特定の文字列値が正しくない可能性がある、特定の値が < 0 であるためスキップする必要があるなどです。これらのエラーは、その時点では異なる性質のものである可能性があります。このマップを返したいのですが、各マップの初期化が実行されるときに、理想的には一度だけ、これらのエラーにフラグを立てることもできます。これを行う最もクリーンな方法は何でしょうか?

4

2 に答える 2

5

これはかなり珍しい要件です。内部エラーにもかかわらず有効な結果を生成できる場合は、おそらくその結果を返す必要があります。そうでない場合は、例外をスローします。

ただし、この追加情報を返したい場合は、大きく分けて 2 つのオプションがあります。

  1. オブジェクト指向の変更可能な状態。を実行しているときfoo()、何らかのフィールドに内部エラーが蓄積されます。追加のgetFooErrors()メソッドを公開して、呼び出し元が何が起こったかを検査できるようにします。getFooErrorSeverity()また、これらのエラーが結果マップの品質にどの程度影響したかを発信者に伝える必要がある場合は、おそらくメソッドです。
  2. 不変/機能的。上記の情報 (例外と重大度スコア) をメソッドの一部として返します。を返す代わりにMap<String, BigDecimal>、マップと例外の詳細を含むオブジェクトを返します。例えば:

    public class FooResult {
        public final Map<String, BigDecimal> result;
        public final List<Throwable> errors;
        public final int errorSeverity;
    
        // Constructor elided
    }
    

java.io.PrintWriter最初のアプローチは、標準ライブラリでの動作に似ています。I/O メソッドで発生したすべての IOExceptions を飲み込み、checkError()メソッドを公開して、ライターで例外が発生したかどうかを呼び出し元が確認できるようにします。

スレッドセーフに影響を与えず、クライアントにすべての情報を事前に提供し、エラーが発生したスコープとうまく結合されているため、私は 2 番目の方法を好みます。

于 2012-10-29T12:59:49.017 に答える
2

これを行う正しい方法はありませんがFooResult、マップとエラーのリストを含む特別なクラスを作成するのはどうですか (ただし、通常、回復不能なエラーは例外と共に報告されるため、むしろ警告と呼びます)。

FooResult foo(Parameter p){ ... }

class FooResult {
  Map<String, BigDecimal> result;
  List<Error> errors;
}

whereErrorは、必要なすべてのエラー情報 (コード、メッセージ、例外など) を含むクラスです。たとえば、次のようになります。

class Error {
  int code;
  String message;
  Throwable cause; // optional, depending on error
  // ...
}

別の方法として、s のリストをErrorパラメーターとして渡し、必要に応じてメソッドによって入力することもできます。たとえば、次のようになります。

Map<String, BigDecimal> foo(Parameter p, List<Error> errors) { 
  ... 
  if (error) {
    errors.add(new Error(10, "Bad error"));
  }
}
于 2012-10-29T12:55:42.513 に答える