見つかった場合にオブジェクトを返すことになっているメソッドがあります。
それが見つからない場合、私は以下を行う必要があります:
- nullを返す
- 例外を投げる
- その他の
見つかった場合にオブジェクトを返すことになっているメソッドがあります。
それが見つからない場合、私は以下を行う必要があります:
回答:
常に値を見つけることを期待している場合、値がない場合は例外をスローします。例外は問題があったことを意味します。
値が欠落しているか存在する可能性があり、両方がアプリケーションロジックに対して有効な場合は、nullを返します。
より重要:コードの他の場所で何をしますか?一貫性は重要です。
GetPersonById(25)
その人が削除された場合はスローされますがGetPeopleByHairColor("red")
、空の結果が返されます。したがって、パラメーターは期待について何かを述べていると思います。
本当にエラーである場合にのみ、例外をスローします。オブジェクトが存在しないことが予想される場合は、nullを返します。
そうでなければ、それは好みの問題です。
原則として、メソッドが常にオブジェクトを返す必要がある場合は、例外を使用してください。時々発生するnullを予期していて、それを特定の方法で処理したい場合は、nullを使用してください。
あなたが何をするにせよ、私は3番目のオプション、「WTF」を示す文字列を返すことを強くお勧めします。
nullがエラーを示さない場合は、nullを返します。
nullが常にエラーの場合は、例外をスローします。
nullが例外になる場合は、2つのルーチンをコーディングします。1つのルーチンは例外をスローし、もう1つはオブジェクトを出力パラメーターで返すブールテストルーチンで、オブジェクトが見つからなかった場合はfalseを返します。
Tryルーチンを誤用するのは難しいことです。nullをチェックするのを忘れるのは本当に簡単です。
したがって、nullがエラーの場合は、次のように記述します
object o = FindObject();
nullがエラーでない場合は、次のようなコードを記述できます。
if (TryFindObject(out object o)
// Do something with o
else
// o was not found
find
し、findOrFail
Laravel雄弁から
TryFindObject
メソッドから返されるマルチプロパティオブジェクトを定義することではなかったでしょうか?タプルは、複数の値をカプセル化するオブジェクトを定義するために時間をかけたくないプログラマにとって、より怠惰なパラダイムのように見えます。それは本質的にすべてのタプルがとにかくコアにあるということです。
前述のオプションを要約して、いくつかの新しいオプションを投入したいと思います。
または、これらのオプションを組み合わせることができます。
ゲッターのオーバーロードされたバージョンをいくつか提供して、呼び出し元がどちらの方法に進むかを決定できるようにします。ほとんどの場合、最初のものだけが検索アルゴリズムの実装を持ち、他のものは最初のものをラップするだけです:
Object findObjectOrNull(String key);
Object findObjectOrThrow(String key) throws SomeException;
Object findObjectOrCreate(String key, SomeClass dataNeededToCreateNewObject);
Object findObjectOrDefault(String key, Object defaultReturnValue);
実装を1つだけ提供することを選択した場合でも、契約を明確にするためにそのような命名規則を使用することをお勧めします。これは、他の実装も追加することを決定した場合に役立ちます。
あなたはそれを使いすぎてはいけませんが、多くの異なるエラー処理規則を持つ何百もの異なるアプリケーションで使用するヘルパークラスを書くとき、それは役立つかもしれません。
Expected<T> findObject(String)
場所Expected<T>
な機能を持ってorNull()
、orThrow()
、orSupplied(Supplier<T> supplier)
、orDefault(T default)
。これは、エラー処理からのデータの取得を抽象化します
nullオブジェクトパターンを使用するか、例外をスローします。
Person somePerson = personRepository.find("does-not-exist");
このメソッドがIDに対してnullオブジェクトを返すと仮定しましょうdoes-not-exist
。では、正しい動作は何でしょうsomePerson.getAge()
か?現時点では、nullオブジェクトパターンがエンティティルックアップの正しいソリューションであるとはまだ確信していません。
例外をスローする利点:
例を使用した詳しい説明については、http://metatations.com/2011/11/17/returning-null-vs-throwing-an-exception/を参照してください。
あなたの言語とコードが促進するかどうかに依存します:LBYL(あなたが跳躍する前に見てください)またはEAFP(許可よりも許しを求める方が簡単です)
LBYLは、値をチェックする必要がある(したがって、nullを返す)
と言っています
上記に同意しますが、例外は例外/エラー条件に使用する必要があり、チェックを使用する場合はnullを返すのが最適です。
EAFPとLBYLのPython:
http ://mail.python.org/pipermail/python-list/2003-May/205182.html
(Web Archive)
例外は、契約による設計に関連しています。
オブジェクトのインターフェースは実際には2つのオブジェクト間のコントラクトであり、呼び出し元はコントラクトを満たす必要があります。そうでない場合、レシーバーは例外で失敗するだけです。2つの可能な契約があります。
1)メソッドのすべての入力が有効です。この場合、オブジェクトが見つからない場合はnullを返す必要があります。
2)一部の入力のみが有効です。つまり、見つかったオブジェクトになります。その場合、呼び出し元が入力が正しいかどうかを判断できるようにする2番目のメソッドを提供する必要があります。例えば
is_present(key)
find(key) throws Exception
2番目のコントラクトの両方のメソッドを提供する場合に限り、例外がスローされても何も見つかりません。
オブジェクトが見つからないことの意味によって異なります。
通常の状態の場合は、nullを返します。これはたまに発生する可能性があることであり、発信者はそれを確認する必要があります。
それがエラーの場合は、例外をスローします。呼び出し側は、オブジェクトが見つからないというエラー状態をどうするかを決定する必要があります。
最終的にどちらでも機能しますが、ほとんどの人は、例外が発生した場合にのみ例外を使用することをお勧めします。
ここにいくつかの提案があります。
コレクションを返す場合は、nullを返さずに、空のコレクションを返します。これにより、最初にnullチェックを行わなくても列挙を簡単に処理できます。
いくつかの.NET APIは、thrownOnErrorパラメータのパターンを使用して、オブジェクトが見つからない場合に、それが本当に例外的な状況かどうかを呼び出し元に選択させます。Type.GetTypeはこの例です。BCLのもう1つの一般的なパターンは、ブール値が返され、値が出力パラメーターを介して渡されるTryGetパターンです。
状況によっては、デフォルトまたは動作のないバージョンのいずれかであるNull Objectパターンを検討することもできます。重要なのは、コードベース全体でnullチェックを回避することです。詳細については、こちらをご覧くださいhttp://geekswithblogs.net/dsellers/archive/2006/09/08/90656.aspx
例外をスローする代わりにnullを返し、nullの戻り値の可能性をAPIドキュメントで明確に説明します。呼び出し側のコードがAPIを尊重せず、nullケースをチェックしない場合、おそらくいずれにせよ、何らかの "nullポインタ例外"が発生します:)
C ++では、オブジェクトを検索するメソッドを設定する3つの異なる方法を考えることができます。
オプションA
Object *findObject(Key &key);
オブジェクトが見つからない場合はnullを返します。素敵でシンプル。これで行こう。以下の代替アプローチは、out-paramsを嫌わない人のためのものです。
オプションB
void findObject(Key &key, Object &found);
オブジェクトを受け取る変数への参照を渡します。オブジェクトが見つからない場合、メソッドは例外をスローしました。この規則は、オブジェクトが見つからないことが本当に予期されていない場合に適しています。したがって、予期しないケースであることを示すために例外をスローします。
オプションC
bool findObject(Key &key, Object &found);
オブジェクトが見つからない場合、メソッドはfalseを返します。オプションAに対するこれの利点は、1つの明確なステップでエラーケースをチェックできることです。
if (!findObject(myKey, myObj)) { ...
例外はあるべき例外。null を返すことが有効な場合は null を返します。
メソッドがコレクションを返す場合、空のコレクションを返します(上記のように)。ただし、Collections.EMPTY_LISTなどは使用しないでください。(Javaの場合)
メソッドが単一のオブジェクトを取得する場合、いくつかのオプションがあります。
nullを返す場合は注意してください。あなたがプロジェクトの唯一のプログラマーではない場合、実行時にNullPointerExceptions(Javaまたは他の言語では何でも)が発生します。したがって、コンパイル時にチェックされないnullを返さないでください。
null
。詳細については、トップ投票の回答をご覧ください。
ライブラリまたは例外をスローする別のクラスを使用している場合は、それを再スローする必要があります。ここに例があります。Example2.javaはライブラリのようなもので、Example.javaはそのオブジェクトを使用します。Main.javaは、この例外を処理する例です。呼び出し側のユーザーに意味のあるメッセージと(必要な場合は)スタックトレースを表示する必要があります。
Main.java
public class Main {
public static void main(String[] args) {
Example example = new Example();
try {
Example2 obj = example.doExample();
if(obj == null){
System.out.println("Hey object is null!");
}
} catch (Exception e) {
System.out.println("Congratulations, you caught the exception!");
System.out.println("Here is stack trace:");
e.printStackTrace();
}
}
}
Example.java
/**
* Example.java
* @author Seval
* @date 10/22/2014
*/
public class Example {
/**
* Returns Example2 object
* If there is no Example2 object, throws exception
*
* @return obj Example2
* @throws Exception
*/
public Example2 doExample() throws Exception {
try {
// Get the object
Example2 obj = new Example2();
return obj;
} catch (Exception e) {
// Log the exception and rethrow
// Log.logException(e);
throw e;
}
}
}
Example2.java
/**
* Example2.java
* @author Seval
*
*/
public class Example2 {
/**
* Constructor of Example2
* @throws Exception
*/
public Example2() throws Exception{
throw new Exception("Please set the \"obj\"");
}
}