0

私はJavaにかなり慣れていないので、例外とそれらをいつ使用する必要があるかについて頭を悩ませています。私はそれらをエラーチェックの形式として使用してきましたが、例外はユーザーエラーなど、プログラムの制御外のものにのみ使用する必要があると言っている人に出くわしました。

2 次元の特定の行について、xMin と xMax の間のすべての y 値を計算する関数があります。垂直線上の y のすべての値を計算することは不可能であるため、この関数は、線が垂直である場合に例外をスローします。2 つの y 値の間の点を見つける同等の関数もあり、線が水平である場合はエラーがスローされます。

findPointsInRangeOfX (int xMin, int xMax) throws LineIsVerticalException {
    // check if line is vertical
    // if vertical, throw an exception
    // else calculate the y values for each integer between xMin and xMax
    // return y values
}

この関数は、x と y の最小値と最大値で指定されたウィンドウ内のライン上のすべてのポイントを見つけることの一部として呼び出します。この関数では、線が垂直かどうかはチェックしません。代わりに、findPointsInRangeOfX でのチェックに依存し、メソッドの周囲で try および catch ブロックを使用します。

pointsInWindow (int xMin, int xMax, int yMin, int yMax) {
    try {
        // Find list of all the points between xMin and xMax.
        // Remove from list all points not between yMin and yMax
    }
    catch (LineIsVerticalException e) {
        // If line is vertical, cannot find points between xMin and xMax
        try {
            // Instead, find list of all points between yMin and yMax
            // Remove from list all points not between xMin and xMax
        }
        catch (LineIsHorizontalException e) {
            // This part will never be reached because the line is vertical
            // But the compiler complains if the exception isn't caught
        }
    }
}

これでよろしいですか?私はそのようなエラーの例外をスローしていません-垂直線を持っても問題はありません-しかし、それを使用して、x 値ではなく y 値の間のポイントを見つける必要があることを pointsInWindow に伝えています。try catch ブロックを使用するのではなく、pointsInWindow 関数で線が垂直かどうかを確認するチェックを複製する必要がありますか? チェックを複製した場合、LineIsVerticalException をまとめて削除する必要がありますか?

4

4 に答える 4

6

単一責任の原則に従う必要があります。すべてのメソッドは 1 つのことを行います。現在、メソッドは 2 つのことを行っています。それが垂直/水平かどうかを確認し、何かを計算します。

ここでもう 1 つ注意してください: プログラム フローに例外を使用しないでください。

次のように分割する必要があります。

bool isVertical(parameters){}
bool isHorizontal(parameters){}
SomeClass CalculateVertical(parameters){}
SomeClass CalculateHorizontal(parameters){}

プログラム フローは次のようになります。

if(isVertical(something)){
 CalculateVertical(something);
else if (isHorizontal(something)){
 CalculateHorizontal(something);
}

実装例:

SomeClass CalculateVertical(something){
 if(!isVertical(something)) { throw new IllegalArgumentException() }
 // Calculations
}

この例外は、プログラマがキャッチする必要がないことに注意してください。

于 2013-10-22T12:18:36.567 に答える
1

または、以下のように変更できます。

pointsInWindow (int xMin, int xMax, int yMin, int yMax) {
    try {
        // Find list of all the points between xMin and xMax.
        // Remove from list all points not between yMin and yMax
    }
    catch (LineIsVerticalException e) {
        // If line is vertical, cannot find points between xMin and xMax
        // do something..
        }
    catch (LineIsHorizontalException e) {
        // unless LineIsVerticalException is superclass of LineIsHorizontalException,
        // this will work 
        // do something ..
        }
    }
}
于 2013-10-22T12:25:24.987 に答える
1

一般的に、境界的なケースではなく、予期しない問題 (ネットワーク障害など) に対して例外を使用するようにしています。ただし、それはあいまいな区別であり、特定のアプリケーション コンテキストに依存します。

特にあなたの問題のために。機能の分割についてはどうですか。指定された線が水平か垂直かを検出する 2 つの関数を作成します (例: boolean isVertical());。

pointsInWindow 関数では、最初に垂直/水平線の特殊なケースを扱っているかどうかを確認し、そうでない場合はさらに findPointsInRange メソッドを呼び出すことができます。

これは DRY 原則のDRY 原則に違反し、コードの保守時にさらに問題を引き起こす傾向があるため、ロジックを複製しないようにしてください。

これが役に立てば幸いです、マーカス

于 2013-10-22T12:27:15.340 に答える