コンストラクタで例外を投げていいのか?
自分はコンストラクタで例外を投げる派。
これはオブジェクトを生成する条件を満たしていないのであれば、
そもそも生成させないようにしたいから。
golang で書くとこんな感じ。
golang は例外ないから error を返してるだけだけど・・・。
obj, err := NewObj()
以下のように Valid でチェックするのはあんまり好きじゃない。
obj := NewObj() err := obj.Valid()
とはいえ、任意のタイミングで Valid() かけたいケースもあるので、
「Valid() 自体を定義したくない」ということではない。
あくまでコンストラクタでオブジェクトを生成できないケースでは
例外を投げたい(生成できないようにしたい)というだけ。
ちなみに、ActiveRecordとかはこのパターンだから、これに従って実装します。
そこをオレオレルールにするとかはNGな気がする。
で、「コンストラクタで例外投げる」についてググると結構記事が出てくる。
以下によるとJavaでは Fileがコンストラクタで例外を投げるらしい。
http://d.hatena.ne.jp/pasela/20061129/1164947268
たしかに投げてる・・・。
http://docs.oracle.com/javase/jp/7/api/java/io/File.html#File(java.net.URI)
ということで、
その言語のコアなパッケージとか確認して、
コンストラクタで投げているのであれば、
投げていいんじゃないかな・・・・。
っていうなんとも微妙な結論になった・・・。
twitterで以下のコメントをいただきました。
@pospome これはもともとc++のコンストラクタで例外が発生するとデストラクタが呼ばれないため禁じ手みたいにされていたっていう経緯があるんですが、GC搭載の言語なら問題ないと思います。
— Motonobu Kuryu (@arc279) 2016年7月13日