null を返してはいけないのかなあ?
「nullを返してはいけない理由(Saisse's Wiki 2004-04-06)」について。
面白く読みました。
確かにnullを返そうかどうしようか、迷う状況も数多くあります。ただ、ちょっと反対意見を。
すごくありきたりな結論だけど、null を返すことはアリでしょう。
理由は「null は取り得る値の範囲の一部」だから。
安易に null を返すことはモデルのバグの放置につながる、というのはすごくよく分かります。
ただ、それも「安易に」というただし書きレベルのような気がします。要は契約をどこで交わすかという話ではないかと。
サンプルコードに次のようなインタフェースが挙げてありました。
Hoge getHoge();
boolean isHogeGettable();これはすなわち次のコードと(意味的には)同義だと考えます。
/**
* @return Hoge オブジェクト。存在しない場合には null
*/
Hoge getHoge();
「(1)あるかどうかを判定し、(2)ある場合にのみ値を取得する」というプロトコルをクライアントに規定するという意味では、差がないように思います。
また、isHogeGettable()メソッドがあろうとなかろうと、getHogeメソッドは null を返すべきでしょう。getterメソッドに assert が書いてありますが、これは setter 内もしくは getter のクライアント側コード内に配置するべきだと思います。
逆に null を返せないと困る状況があります。たとえば範囲クラスの類です。
class DateRange
Date getStart(); //日付の最初を返す
Date getEnd(); //日付の最後を返す
}
class IntRange {
int getStart(); //最初の数値を返す
int getEnd(); // 最後の日付を返す
}
範囲の片方が開放されているRangeももちろん存在します。その場合は null を返すようにしたい。しかし IntRange クラスの値はプリミティブ型で扱いたいので、返すのに適当な値がありません。
Integer 型を返すのも嫌に感じて、hasStart()/hasEnd()メソッドを追加しました。
(「null を返すべきじゃない」という立場にたつと、DateRangeクラスでも hasXXXXメソッドを採用することになるはずです。ただし、それでも getter は null を返すように設計したい)
もちろん、次のようなインタフェースで null を返されるのは非常に困りもの。
0件のCollection を返して欲しいところです。
(速攻で NullPointerException が出ることでしょう)
/**
* 指定の条件で問い合わせた結果の一覧を取得します。
* @param criteria 検索条件
* @return 見つかった Foo オブジェクトのコレクション
*/
Collection queryFoo(Criteria criteria);


Comments
Googleからたどり着きました。
isHogeGettable() + getHoge()とgetHoge() + コメントは「動けばいい」という意味では一緒ですが、オブジェクト指向的には一緒ではないです(インターフェースありきがオブジェクト指向の基本だと思ってますので)。
getterのassertionはクライアントにisGettable()の存在を示すためにあります(要はコメントの代わりです)。なのでgetterにあるのはそんなには間違いではないです。
それとプロトコルという意味でもnullによる判断は不明確さを持つので、同じとは言えないと思うのですがどうでしょうか?
あと、nullが返せないと困るという状況はちょっと理解できませんでした。nullが返ってくると困る状況は多々ありますが(汗)。
Posted by: Saisse | 2004.04.11 at 06:34 PM