私は Java プロジェクトに取り組んでおり、興味深い設計上の問題に遭遇しました。それは正確には問題ではありませんが、明らかな解決策では少し醜いです。
Callable を実装するクラスがありますが、現在の実装では、少なくとも呼び出し元のスレッドに関する限り、結果に興味がないのと同じくらい簡単に Runnable になる可能性があります。呼び出しスレッドは、これらのいくつかをスレッド プールにドロップします。これらの Callable のそれぞれには、外部サービスから取得されたデータのバッチがあります。Callables は多くのアクションを実行しますが、その多くは外部サービスへのさらなる呼び出しを伴います。その結果、さまざまな例外がスローされる可能性のある場所が多数あります。
私が見つけた問題は、例外が発生した場所に応じて、さまざまなアクションを実行する必要がある場合があることです。ポイント A で発生した場合は、外部サービスのデータを削除します。ポイント B で発生した場合は、データをサーバー上の別の場所に移動します。ポイント C で発生した場合は、ログに記録するだけで、それ以上何もしません。複数のポイントで任意の数の例外タイプをスローできますが、タイプ自体で多くのフィルタリングを行う必要はないと思いますが、さらにそれが発生しました。
Callable 自体はそれほど大きくないので、いじるコードはそれほど多くありません。ただし、さまざまな処理が必要な可能性のあるすべてのポイント/例外を処理するために、大量の try/catch ブロックを使用してそれを処理することをためらっています。これが本当に唯一の実行可能な解決策かもしれないことを認識しています。既存の例外をキャッチして独自の例外を再スローすることなく、スローされる例外のほとんど (おそらく少数) を実際に制御することはできません。これは少し冗長に思えます。この種のことを処理するための良いパターンまたは方法があるかどうか疑問に思っています。
例外処理クラスを検討しましたが、例外がスローされた時点が重要であるため、各 Exception を何らかの方法でキャッチしてハンドラーに渡す必要があります。Callable をよりアトミックなクラスに分割し、それぞれに独自の小さなブロックと処理を持たせることもできますが、それは別のクラッジと交換することになります。call() メソッドですべてを完全にキャッチするか、呼び出し元のスレッドで Exception from the Future を取得することは、実際には選択肢ではありません。まさに実行可能。
誰でも光を当てることができますか?たぶん、私は try/catch ブロックについて口論しているだけなので、それを先に進めるべきですが、もっと良い方法があるに違いないと感じています...
うーん、メソッドの注釈がここで役立つかもしれないと思います。それぞれのメソッドに例外をスローする可能性のあるコードが 1 つだけになるまで、すべてのメソッドを分解できます。これらのそれぞれに、そのメソッドが例外をスローしたときに何が行われるかを指示するカスタム アノテーションを付けます。それが可能かどうかはわかりません(例外は、データの各部分を処理するループ内で発生する可能性があり、1つの部分だけが問題になる可能性があるため、何らかの方法でその部分を処理するようにマークする必要があるため、何らかの方法でその部分をキャッチする必要がありますチェーンのさらに上)、おそらくこれにより、多くの try/catch ブロックの必要性が軽減され、代わりに単一の注釈と例外を処理するハンドラー クラスで動作を処理できます。アノテーションでこのように動作を指示することは可能だとは思いませんが、私は'