0

次のファイルを読みたいとします。

TestFile;100

クラスのフィールドに:

public class MyReader { 
    String field1;
    Integer field2;
}

コンテンツを読むには、わずかに異なる 2 つの方法があります。

パブリック クラス MyReader {

public void loadValues(File file) throws IOException {

    //a generic method that reads the content file to a string throwing an IOException
    String line = readFileToString(file);
    String[] values = line.split(";");

    field1=values[0];
    field2=Integer.parseInt(values[1]);

}

//then i'll have well known getters:

public String getField1() {
  return field1;
} 

public Integer getField2() {
  return field2;
}

次に、2 番目の慣用句:

private String[] values; //made the values a class field

public void loadValues(File file) throws IOException {

    //a generic method that reads the content file to a string throwing an IOException
    String line = readFileToString(file);

    values = line.split(";");

}

public String getField1() {
  return values[0]
} 

public Integer getField2() {
  return Integer.parseInt(values[1]);
}

大きな違いは例外管理にあります。どちらの場合にも発生する可能性のある 2 つの実行時例外をキャッチすることを意図的に省略しました。

  • ArrayIndexOutOfBoundsExceptionファイルに含まれるフィールドが 2 つ未満の場合
  • NumberFormatException整数の解析が失敗した場合

最初のアプローチ
すべてのフィールドが起動時にロードされます。そのうちの 1 つが解析可能でなくても十分ですNumberFormatException。. 必要なフィールドよりもフィールドが少ない場合、範囲外の例外が発生します。特に、特定のフィールド値を使用するという事実の背後にあるすべてのフィールド値の正確性を確保したい場合: 高速パラダイムに失敗します。100 個のフィールドがあり、レコードにエラーが含まれており、そのエラーがトラブルシューティングのためにファイルに記録されているとします。そのまま、このコードは次のようになります。

Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)

つまり、エラー、エラーの原因となった値、エラーが発生した行番号を取得しますが、フィールド名は取得しません。開発者にとっては良いことですが、通常ソース コードにアクセスできないシステム エンジニアにとってはあまり良いことではありません。

2 番目のアプローチフィールドは、 getter を介してアクセスされた場合にのみ
、データ文字列から「抽出」されて解析されます。各ゲッターは、まったく同じ状況で、上記の 2 つのエラーを返す場合があります。「フェイル ファスト パラダイム」とは対照的に、ある程度の「フォールト トレランス」があります。レコードの 100 番目のフィールドに正しくない値が含まれていても、クラスのクライアントがゲッターを呼び出さない場合、例外はスローされません。一方、不正な値のゲッターが呼び出されると、ログに記録された例外には、問題の原因となったフィールドの情報が含まれます (スタック トレース内)。

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:449)
at java.lang.Integer.parseInt(Integer.java:499)

at com.test.MyReader.getField2(MyReader.java:39)

at com.test.MyReader.test(MyReader.java:33)
at com.test.MyReader.main(MyReader.java:16)

質問

どちらのアプローチにも長所と短所があり、どちらを採用するかの決定はコンテキストに依存すると言えます。質問は次のとおりです。

  • ゲッターとセッターは JavaBeans のサブジェクトです。彼らが例外を返すことは「受け入れられる」のですか?
  • 2 つのアプローチのクラスは、明らかに同じインターフェイスを持っている可能性がありますが、例外のアーキテクチャがまったく異なるため、クライアントはそれらをまったく異なる方法で使用することになっています。では、この事実をクライアントにどのように伝えればよいのでしょうか? ゲッターのセマンティックが誤解を招く可能性があります。おそらくもっと雄弁な方法がありますか?
4

1 に答える 1

2

まず、values []配列をローカル変数として格納し、他の関数(この場合はゲッター)にアクセスできないため、2番目のアプローチは機能しません。

次に、公開するAPIは誤解を招き、どの規則にも準拠しないため、ゲッターに例外をスローしないでください。

第3に、文字列を自分で解析する代わりに、すぐに使用できるライブラリをcsv解析に使用することを検討し、車輪の再発明を行わないでください。http://opencsv.sourceforge.net/

第4に、csvレコード用の単純なPOJOオブジェクトを作成します。各フィールドに値を割り当てながらエラーをチェックしてから、例外をスローするかどうか、デフォルト値を指定するなどができます。

お役に立てば幸い

于 2012-06-15T10:00:10.210 に答える