1

私はいくつかのチームコードを見直していて、次のようなものを見つけました:

MyObj obj = null;

try {
  obj = myService.findObj(objId)
} catch (MyObjNotFoundException e) {
  // The object wasn't found, it's the "normal" path
  // Here they create the object in DB (but don't touch the obj variable)
  // There is about 60 line of code
}
if (obj != null) {
  // The object already exist, logs are written and some queue is filled
  // with current objId to be processed later on
}

私のレビューでは、 を使用Exceptionして通常のプログラム フローを制御することは、パフォーマンスや保守性の点で良い考えではないことを書きます。null最良の方法は、例外をスローする代わりに返すようにサービスを変更することですが、次のようになります。

  • 彼らがサービスを所有しているかどうかはわかりません (別のプロジェクト/チームである可能性があります)
  • 彼らは本当にこの例外を別の場所で必要とするかもしれません

したがって、例外をスローしない限り解決されないパフォーマンスの問題は別として、「よりクリーンな」コードを提供したいと思います。

サービスがこの Exception のみを送信することを知っている私の考えは次のとおりです。

try {
  obj = myService.findObj(objId)
} finally {
}

if (obj == null) {
  // The object wasn't found, it's the "normal" path
} else {
  // The object already exist, logs are written and some queue is filled
  // with current objId to be processed later on
}

あなたはこの道を行きますか?それは本当に読みやすさへの一歩を踏み出しますか? 何か他のことを考えますか?

どうもありがとう。

4

6 に答える 6

2

あなたの提案では、サービスが ObjectNotFoundException をスローする場合、メソッドもスローします。サービスの署名を変更することなく、コードが現在行っていることは、それを行う唯一の方法です。

または多分あなたは意味した

try {
    obj = myService.findObj(objId)
} 
catch (ObjectNotFoundException) {
    // ignore, obj stays null
}

if (obj == null) {
    // The object wasn't found, it's the "normal" path
} 
else {
    // The object already exist, logs are written and some queue is filled
    // with current objId to be processed later on
}

これは現在のコードと非常によく似ています。いずれにせよ、コードをよりきれいにするためにIMHOで行うべきことは、通常のパスの60行のコードを別のメソッドに抽出し、それ自体をいくつかのサブメソッドに分割することです。

于 2012-09-27T14:20:26.040 に答える
1

Exceptionロジックが、正常に実行されているシステムに表示されるとは予想されないことを頻繁に実行する場合に非常に適しています。たとえば、各Personオブジェクトには1つ必要firstnameです。名が1つ含まれていない人は例外的なものであり、を使用して扱う必要がありますException

それどころか、null状況が「正常」であるが、重要な結果を伴わないことを示すために使用します。同じ例を維持するために、人は2つの名を持つことができますが、それは実際にはオプションです。この場合、呼び出される概念メソッドretrieveSecondFirstName()は効果的に戻りnullます。

Null Pattern私は適応したときに使用することを好みます。http://en.wikipedia.org/wiki/Null_Object_patternを見てください

さらに、スローExceptionまたは使用することで、クライアント側Null Patternの一般的なケースを回避できます。NullPointerExcetion

于 2012-09-27T14:21:05.630 に答える
1

個人的には、あなたの変更が大きな違いをもたらすとはまったく思いません。おそらく、Java バイト最適化の知識が豊富な人なら参加できるかもしれませんが、例外ブロックに何もない場合でも、例外処理の余分な「重み」がまだ組み込まれていると思います。

例外処理をフロー制御として使用しないようにする最大の理由の 1 つは、例外をスローする費用がかかるためです。コンパイラは、例外処理を最適化するようには設計されていません。彼らは、例外的な状況でのみスローされることを期待しています (しゃれを許してください) - つまり、アプリケーションが予期しない状況に遭遇したときです。したがって、標準的なフロー制御ロジック (if/else、for、while など) の最適化に重点が置かれています。フロー制御に例外を使用することは、可読性の観点からも、パフォーマンスの観点からも、ひどい考えです。

オブジェクトが見つからないことは、予期しない状況ではありません。実際、コードを開発し、期待される結果に基づいて適切な戻り値を文書化する前に設計する必要があるのは、ロジック/フローチャートの一部です。DB 応答の失敗は許容可能な例外条件です。これは非常にまれに発生するものであり、実際には予期しない状態です。

本質的に、あなたが提案している変更は、私の見解では、それをさらに読みにくくしています。問題の核心は、スローされる例外です。それが解決できない場合、空の try/catch が本当に非常に役立つとは思えません。どちらかといえば、コードは最初に、見つからない例外をすべて無視する予定であると述べていますが、後でそれを処理することを選択します。これはやや矛盾しています。それによってパフォーマンスが向上した場合、それは私が理解できることですが、私が言ったように、最もコストのかかる部分は実際に例外をキャッチするのではなく、例外をスローすることだと思います.

于 2012-09-27T14:20:02.217 に答える
0

これを行う正しい方法も間違った方法もありません。ObjectNotFoundException-patternは、J2EE および EJB 2.0 の初期の頃から存在していたとしか言えません。典型的なビジネス ロジックの一部が約 17 兆個の迷惑なチェック例外をキャッチし、それらのほとんどをラップして Nirvana に再スローできるようにする必要がFinderExceptionあるときに、そのサブクラスをスローするのが一般的でした。RuntimeExceptions

nullオブジェクトを見つけられないことはとにかくそのような例外ではなく、null正確にそのセマンティクスを持っているため、今日では、戻ることは再び一般的になっている可能性があります。それ以外は、 にnull勝るものはありませんObjectNotFoundException。好みの問題です。

于 2012-09-27T14:18:08.253 に答える
0

明確な答えはありません。findObj() がどのように機能するかによって異なります。ほとんどの場合、オブジェクトを返しますか? オブジェクトが見つからない場合、それは例外的な状況ですか、それは予期しないことですか? この場合はそうではないと思います。ここでは null を返します。例外ベースのバージョンは、読み取りと保守が困難です。

于 2012-09-27T14:31:28.513 に答える
0

エラーが発生した理由をユーザーに渡すことができるため、null を返す代わりに例外を使用するのが好きです。私の観点からは、単に null を返すよりも優れています。

于 2012-09-27T14:14:58.280 に答える