web-dev-qa-db-ja.com

オブジェクト指向コードをバグ修正するためのアドバイス:なぜデータが設定されないのですか?

オブジェクト指向(Java)コードをデバッグする場合、オブジェクトの一部のフィールドがnullであるのに、そうではない場合があります。私はしばしば、それがどこに設定されるべきかを理解しようとすると、あまりにも多くの時間を費やします(その時点で、何が悪かったのかがすぐに明らかになることがよくあります)。

それが関数の引数だったとしたら、ブレークポイントを設定してスタックトレースをたどることで、どこから来たのかを簡単に追跡できます。

しかし、OtherThingからThingListを取得するThingFunctionsクラスがあり、リスト内のThingにIDがない場合、通常、Thing.idThingList.addOtherThing.setThingListのすべての使用法をチェックします。 IDの設定の責任者を見つけるためだけに。

ブレークポイントは、何かが発生した場所ではなく、何かが発生した場所を教えてくれるので、あまり役に立ちません。

これは、引数がnullである理由を見つけるために、スタックトレースをたどるよりも桁違いに時間がかかります。この問題をデバッグするための同様に簡単な解決策はありますか?一般的なアドバイスはありますか?私は最新のIDEを持っていますが、他のツールも歓迎します。

3
Mark

オブジェクトの状態を処理する方法は2つあります:

  1. 非常に高度なデバッグスキルがあり、わかりにくいバグを見つけることができます。
  2. あいまいなバグが最初から発生しないように、より良い方法で状態を管理します。

オブジェクトの状態をより適切に管理する方法:

  1. コンストラクターを使用して、状態がすでに有効なオブジェクトを作成します。
  2. 州を非公開にします。
  3. 状態の変化を検証するセッターメソッドを記述します。無効な状態変更をブロックします。
  4. 必要に応じて、不変オブジェクトを使用してください。
11
Robert Harvey

考えられる解決策の1つは、オブジェクトのフィールドが常にコンストラクターに設定されるようにすることです。多くの場合、これはコンストラクタがこのフィールドの値を引数として取ることを意味します。事後にフィールドを設定することを忘れるよりも、コンストラクターに引数を渡すことを忘れる方がはるかに困難です。

潜在的な欠点は、このフィールドの値が何であるかを理解するまでオブジェクトを作成できないことです。時々(通常は?)、これに対する解決策は非常に簡単です。フィールドの値がどうあるべきかがわかるまで、オブジェクトを作成するだけですしないでください

3
Tanner Swett

最も一般的なアドバイスは次のとおりです。属性を非公開にします。

オブジェクトはその状態の責任を負い、他のユーザーが有効な状態であることに依存するべきではありません。クラスのAPIは、データ操作ではなく動作を提供する必要があります。

1
Alex Favieres

これはかなり広い質問であり、一般的な答えは「優れたアーキテクチャと設計を使用する」です。デバッグは役に立ちませんが、コードを正しく設計することは役に立ちます。

  • SOLID原則に従ってアプリケーションを設計します。
  • 不変のデータ構造を使用します。
  • 事前条件と事後条件を適用します(つまり、すばやく失敗します)。常にオブジェクトを有効な状態に構築するか、そうでなければクラッシュします。
  • パブリックインターフェイス全体でnull参照を許可しないでください(プログラミング言語でnull参照を回避できない場合は、クラス内で問題ありません)。
  • プリミティブの代わりに値タイプを使用します(プリミティブの執着を参照)。
  • ドメイン駆動設計の手法を使用します。

nullsに問題があることは間違いなく、そのため、発明者はこれを「10億ドルの間違い」と呼んでいます。

私の箇条書きはかなり一般的ですが、グーグルで各トピックを読むことができます。そうすれば、問題を回避するのが上手になる方法を理解できます。

おめでとう!多くのプログラマーは、これが問題であることにさえ気づいておらず、コストのかかるバグのあるコードを書き続けています。

0
jhyot