3

カスタム例外をいつスローする必要がありますか?

たとえば、サーバーに接続するコードがあります。サーバーに接続するコードは、接続に失敗するとIOExceptionをスローします。それが呼び出されるメソッドのコンテキストでは、これは問題ありません。ネットワークコードでも問題ありません。

ただし、これは接続がない(したがって機能しない)ことを表すため、例外はUIまで続きます。この段階では、IOExceptionは非常にあいまいです。NoConnectionExceptionのようなものの方が良いでしょう。

だから、私の質問は次のとおりです。抽象化により適した別の(カスタム)例外を代わりにスローするために、どの段階で例外をキャッチする必要がありますか?

4

5 に答える 5

4

私が元のメソッドに何をするように頼んだかという観点から、例外が話されることを期待します。例えば

read -> ReadException
connect -> ConnectException
buildPortfolio -> FailedToBuildPortfolioException

など。これにより、内部で何が起こっているかが抽象化されます(つまり、ソケットなどを介して接続していますか)。原則として、コンポーネントのインターフェイスを作成するときは、対応する例外または一連の例外を作成することがよくあります。私のインターフェースはと呼ばれComponent、私の例外は通常ComponentException(egRateSourceRateSourceException)です。一貫性があり、完全なコンポーネントセットとしてさまざまなプロジェクトに簡単にエクスポートできます。

欠点は、非常に多くの例外を作成し、非常に多くの翻訳を実行しなければならない可能性があることです。利点は、(あなたが特定したように)抽象化のリークがほとんどまたはまったくないことです。

メソッド呼び出し(したがって例外)の階層のある時点で、回復を実行できない(または不適切な場所にある)と判断し、後で処理するためにチェックされていない例外に変換する場合があります。

于 2009-07-05T13:13:56.970 に答える
1

これが「言語に依存しない」というタグが付けられていることは知っていますが、実際にはそうではないと思います。C ++の観点からすると、例外をスローする基本的な操作はほとんどないと思います。C++標準ライブラリは、ごく少数の場所でのみ例外を使用します。したがって、例外を生成できる最初の場所は、多くの場合、私自身のコードです。そのコードでは、非常にフラットな階層が好きです。コードの後半で何百ものcatch()句をいじりたくないので、クラスと名前空間のバロック階層を作成することに対するJavaとC#の明らかな執着を理解したことはありません。

したがって、私のC ++コードの場合、ライブラリごとに、意味のあるエラーメッセージを含む1つのタイプの例外があります。そして、1つは最終的な実行可能ファイル用です。

于 2009-07-05T13:21:45.440 に答える
1

ここには 2 つの疑問が隠されていると思います: a) 例外をいつ別の例外の背後に隠す必要があるか。b) これに対していつカスタム例外を使用する必要があるか。

a) 私が言いたいのは、例外がアプリケーション内の 2 つのレイヤーの境界を越えて移動するときはいつでも、新しいレイヤーにより適切な例外の背後に隠されるべきであるということです。例: リモート処理を行っているため、ConnectionWhatEverException が発生します。

しかし、発信者は接続の問題を認識すべきではありません。彼は何らかのサービスを実行したいだけなので、ServiceOutOfOrderException を取得します。この理由は次のとおりです。レイヤー内でリモーティングを行う場合、ConnectionException を使用して何か便利なことを行う必要がある場合があります (再試行、バックアウト キューへの書き込みなど)。そのレイヤーを離れると、誰も ConnectionException の処理方法を知りません。ただし、サービスが機能しない場合にどうするかを決定できる必要があります。

b) 一致する既存の例外がない場合。たとえば、Java には便利な例外がいくつかあります。IllegalState と IllegalArgument をよく使用します。新しい例外クラスの強力な議論は、提供する有用なコンテキストがあるかどうかです。たとえば、失敗したサービスの名前は、ServiceFailedException の引数になる可能性があります。メソッド呼び出しごとにクラスを作成しないでください。100 例外クラスは、動作が異なる (つまり、少なくともフィールドが異なる) 限り、問題にはなりません。名前のみが異なり、同じ抽象化レベルに存在する場合は、それらを 1 つの Exception にして、異なる名前をメッセージまたはその例外クラスの 1 つのフィールドに入れます。

c) 少なくとも Java では、チェック例外に関する議論があります。私はチェックされた種類が嫌いなので、それらをチェックされていないものに直接ラップします。しかし、それはアドバイスよりも意見です。

于 2009-07-05T14:58:51.440 に答える
0

IOの問題が原因ではないNoConnectionExceptionが発生する場合はありますか?逆に、原因がIOベースであるかどうかを知ることは、クライアントが賢明に回復するのに役立つのでしょうか。

于 2009-07-05T13:18:09.223 に答える
0

カスタム例外をいつスローする必要がありますか?

I. より多くの (診断) 情報を提供できる場合。

注: この追加情報は、元の例外 (IOException) がスローされた場所では利用できない場合があります。抽象化のプログレッシブ レイヤーには、この例外の原因となった何をしようとしていたかなど、追加する情報がさらにある場合があります。

Ⅱ.実装の詳細を公開してはならない場合: つまり、(錯覚?) 抽象化を継続したい場合。

これは、基礎となる実装メカニズムが変更される可能性がある場合に重要になる場合があります。基になる例外をカスタム例外でラップすることは、クライアントを実装の詳細から隔離する良い方法です (抽象化のレベルを上げることにより)。

III. Ⅰ・Ⅱともに

注: さらに、クライアントは、関心のある正確なレベルの情報にチューニングできる必要があります。または、関心のないものはすべてチューニングできる必要があります。そのため、カスタム例外を IOException から派生させることをお勧めします。

于 2009-07-05T14:21:08.583 に答える