8

メソッドがあるとします

public Patient(int id)
{
    ----
}

IDを指定してPatientオブジェクトを返します。2つの方法でコントラクトを定義できます

  1. 患者が存在しない場合、メソッドは null を返します
  2. 患者が存在しない場合、メソッドは例外をスローします。この場合、Patient がデータベースに存在する場合は true、そうでない場合は false を返すクエリ メソッドも定義します。

どの契約を使用すればよいですか? 他の提案はありますか?

更新: このケースについてもコメントしてください... ID が割り当てられたデータベースではなく、ユーザーが UI に入力したものである場合.. SSN のように.. どちらが優れているか..

私が有効だと思うSteveからのNullパターンについてのコメント: IDが存在しなかったときにすぐに知ることが本当に役立つので、おそらくここでは良い考えではありません.

また、ここのNullパターンはやや重いと思います

Id が悪いために例外をスローすることについての Rob Wells からのコメント: 患者の名前のタイプミスが例外的な状況であるとは思わない」

4

9 に答える 9

14

別の層 (データベースであれアプリケーション サーバーであれ) への "通信" は、実行できる最もコストのかかるアクティビティの 1 つであることを覚えておいてください。通常、ネットワーク呼び出しは、メモリ内呼び出しよりも桁違いに時間がかかります。

したがって、API を構造化して冗長な呼び出しを避けることは価値があります。

API が次のようなものであるとします。

// Check to see if a given patient exists
public bool PatientExists(int id);

// Load the specified patient; throws exception if not found
public Patient GetPatient(int id);

次に、データベースに 2 回ヒットする可能性があります。または、これを回避するために適切なキャッシュに依存することになります。

別の考慮事項は次のとおりです。コードに「既知の適切な」ID がある場所もあれば、ない場所もあります。場所ごとに、例外をスローするかどうかについて異なるポリシーが必要です。

これは、私が過去に効果的に使用したパターンです。2 つの方法があります。

// Load the specified patient; throws exception if not found
public Patient GetExistingPatient(int id);

// Search for the specified patient; returns null if not found
public Patient FindPatient(int id);

明らかに、GetExistingPatient() は FindPatient() を呼び出すことによって構築できます。

これにより、呼び出しコードが適切な動作を取得し、何か問題が発生した場合は例外をスローし、必要のない場合は例外処理を回避できます。

于 2009-01-05T20:03:22.757 に答える
4

もう1つのオプションは、NullObjectパターンです。

于 2009-01-05T19:52:41.530 に答える
4

おそらく例外をスローする必要があります。有効な患者を指していないものがある場合、idそれはどこから来たのですか?非常に悪いことが起こった可能性があります。それは例外的な状況です。

編集:テキストに基づく検索など、整数ベースの検索以外のことをしている場合は、返すのnullが問題ありません。特にその場合、複数の結果(同じ名前、同じ誕生日、または基準が何であれ、複数の患者)が返される可能性があるためです。

検索関数は、検索関数とは異なるコントラクトを持つ必要があります。

于 2009-01-05T19:53:09.143 に答える
2

この状況では、存在しない患者に対してメソッドがnullを返すようにします。

システム自体に問題がある場合は、例外を使用して重大な劣化を支援することを好む傾向があります。

この例では、おそらくmosdtです。

  1. 検索フォームに入力された場合の患者IDのタイプミス、
  2. データ入力エラー、または
  3. 患者の記録がまだ入力されていないというワークフローの問題。

したがって、例外ではなくnullを返します。

データベースへの接続で問題が発生した場合は、メソッドで例外を発生させます。

編集:署名の患者IDが整数であることがわかりました。StevenLoweに感謝します。そのため、理由のリストを修正しました。

ただし、例外をいつ使用するか(システムエラーの場合)と、エラーを返す他の方法(単純なデータ入力のタイプミスの場合)を区別することについての私の基本的なポイントはまだ残っています。私見では。

HTH

乾杯、

ロブ

于 2009-01-05T19:55:36.313 に答える
2

場合によります:

通常の操作でデータベース内のファイルと一致しないセクション番号が生じると考えられる場合は、空の (NULL) レコードが返されます。

ただし、特定の ID が常にレコードにヒットする必要があると予想される場合は、レコードが見つからない場合 (これはまれです)、例外を使用します。

DB 接続エラーのような他のものは、例外を生成する必要があります。
通常の状況では、DB へのクエリは常に機能します (ただし、0 レコードが返される場合と返されない場合があります)。

PS私はポインタを返しません。(ポインタの所有者は??)
レコードを持っているかどうかわからないオブジェクトを返します。しかし、その中の記録の存在について尋問することはできます。潜在的にスマート ポインター、またはコテキストを理解するスマート ポインターよりもわずかにスマートなもの。

于 2009-01-05T20:03:20.747 に答える
1

このような単純な状況では、1。十分すぎるようです。クライアントがnullを返した理由を知るために呼び出すコールバックメソッドのようなものを実装したい場合があります。ただの提案。

于 2009-01-05T19:54:10.640 に答える
1

説明を額面通りに受け取ると、おそらく両方が必要になります。

  • Adamが指摘したように、不正なIDはエラー/例外ですが、
  • 他の場所で消えた可能性のあるIDが与えられた場合は、それらをチェックするためのクエリメソッドが必要になります
于 2009-01-05T19:56:08.653 に答える
0

私がそれを正しく読んだと仮定すると... Patient(100) を呼び出すと、ID が 100 の患者のオブジェクト参照が返されます。ID が 100 の患者が存在しない場合は、null を返す必要があると思います。例外は過剰に使用されている IMO であり、このケースでは必要ありません。関数は単に null を返しました。アプリケーションをクラッシュさせる可能性のあるエラー ケースは作成されませんでした (もちろん、その null を処理せずにアプリケーションの他の部分に渡した場合は除きます)。

特に、ユーザーが特定の ID を持つ患者を検索する検索の一部であり、オブジェクト参照が null になった場合は、その関数が「null」を返すことは間違いありません。そのIDは存在します。

于 2009-01-05T20:00:24.183 に答える
0

例外をスローします。

null を返す場合は、次のようにコーディングします。

Console.WriteLine(Patient(id).Name);

ID が存在しない場合、NullReferenceException で失敗します。これは、PatientNotFoundException(id) と言うほど役に立ちません。この例では、追跡するのはまだ比較的簡単ですが、次のことを考慮してください。

somePatient = Patient(id)

// much later, in a different function:

Console.WriteLine(somePatient);

患者が存在するかどうかをチェックする関数を追加することについて: これは、PatientNotFoundExceptions を完全に防ぐわけではないことに注意してください。例えば:

if (PatientExists(id))
    Console.WriteLine(Patient(id).Name);

-- 別のスレッドまたは別のプロセスが、PatientExists と Patient の呼び出しの間に患者を削除する可能性があります。また、これは 1 つではなく 2 つのデータベース クエリを意味します。通常は、呼び出しを試して例外を処理する方がよいでしょう。

リストなど、複数の値を返すクエリの場合は状況が異なることに注意してください。ここで、一致がない場合は空のリストを返すのが適切です。

于 2009-01-05T20:07:16.167 に答える