質問
次のAPIがあります:
public interface MyApi {
/**
* Performs some stuff.
* @throws MyException if condition C1
*/
public void method() throws MyException;
}
現在、API実装で次の変更を行っています
public class MyApiImpl {
public void method() throws MyException {
if (C1) {
throw new MyException("c1 message");
}
...
}
}
は次のものに置き換えられます:
public class MyApiImpl {
public void method() throws MyException {
if (C1) {
throw new MyException("c1 message");
} else if (c2) {
throw new MyException("c2 message");
}
...
}
}
これはAPIの破損と考えますか?
クライアントのコードは引き続きコンパイルされますが、MyExcepitonが" new"によってスローされるため、API javadocで定義されたメソッドコントラクトはそれ以上尊重されません。条件。
API jarファイルのみが更新された場合、クライアントアプリケーションは引き続き動作しますが、クライアントが例外をキャッチする方法によっては、アプリケーションの動作が大きく変わる可能性があります。
それについてのあなたの視点は何ですか?
解決
はい、C1が発生しない場合に例外をスローすることにより、インターフェイスの規約を破っています。
大まかに言って、インターフェイスの契約が曖昧であるほど、簡単に壊れることはありません。 。
他のヒント
私の観点では、ドキュメントでAPIによって定義されたコントラクトを変更しないでください。新しい振る舞いが必要な場合は、a。)この新しい振る舞いを反映するクライアントが呼び出すことができる新しいメソッドを作成するか、b。)クライアントと変更の必要性について話し合い、それを認識させる必要があります。
これは本当に両方向に進むことができます。あなたとあなたのクライアントの間であなたのアプローチがどうなるかについてです。
c2が何であるかに大きく依存します。既存の契約の論理的な範囲内ですか?その場合、MyExceptionをスローすることで契約を満たします。そうでない場合は、おそらく新しいタイプの例外をスローする必要があります。
私は、チェック例外の大ファンではないことを指摘する必要があります。最終的に、誰かに例外を処理させることは、必ずしもコードをより良くしたり安全にしたりするわけではありません(実際には、誤った例外をだらだらと飲み込む可能性があるため、逆の効果があります)。
MyExceptionがRuntimeExceptionでない限り、「いいえ」、API破損なしと言います。それはそうです。
とにかく、条件C2のMyExceptionをサブクラス化します
C1とC2の両方の条件は「例外的」でなければなりません。私見、私は例外をスローする習慣を作らない
これは破損です。 APIが言語構造によって実施されるか、単に文書化されるかは関係ありません。
この破損がクライアントコードに問題を引き起こすかどうかは別の質問です。欠陥を修正しており、この方法でケースC2をカバーして修正する必要がある可能性があります。その点から、クライアントコードの開発者は、この変更を行ったことに満足しているかもしれません(変更に直面して破損するような方法で現在欠陥を回避していないと仮定!)
ここでの問題は、インターフェイスの一部、実装固有の条件を作成したことだと思います。 「C1」が条件は実装の一部に過ぎないため、「C1」で例外をスローする新しい実装を作成するだけで済みます。または" C2"インターフェースを壊すことなく。