C言語上がりの私にとって、例外処理という存在そのものは知っていたが、概念がC言語になかったので扱いにかなり戸惑う。
そして色々調べてみたけど、例外に関する指針・考え方は本当に多岐にわたっていて、混乱する。
ここでは、自分の解釈をまとめていくのを目標としています。
少しずつ、少しずつ、加筆してまとめていけたらと思います。
例外処理の前提
個人的には、「契約による設計」を前提とした例外処理の考え方がしっくりくる。
なので、基本的にはその考え方から例外処理を扱っていきたいと思う。
会社に買ってもらった「オブジェクト指向入門 第2版 原則・コンセプト」に契約による設計の説明と例外処理のコンセプトが書いてあるっぽい。たぶん必読なので、読む。(ぱっと見たところ、疑似言語とか出てきてて決して読みやすそうとは思わなかったが・・・)
関数失敗時に例外処理を投げるか戻り値で通知するかの指針について
某所で質問したもののまんまになるが、個人的な解釈を以下にまとめる。
論点
- 関数失敗時に例外処理を投げるか、戻り値(例えばboolなど)で通知するか?
- そもそもどういうときに例外を投げるべきか?
前提
事前条件とは・・・メソッドを呼ぶ前に、呼び出し側が成立させる条件。つまり、引数が正しいことや、呼び出すタイミングが正しいことなど。
例外として扱うもの
- 事前条件を満たさない場合、または事前条件を満たさないことによりメソッド内でエラーが起きた場合
(事前条件を満たすのは呼び出し側の責任であるという「契約による設計」の考え方)- 引数異常を起因としてメソッドが正常に動作できなくなった場合もここに該当する
- 事前条件を満たしているが、失敗責任の所在がメソッド内で閉じていない場合(失敗がネットワークなどに起因する場合)
- 事前条件を満たしているが、メソッド内で回復できないエラーが発生した場合
例外として扱わないもの
- 事前条件を満たしており、メソッド内で想定内の処理失敗(=回復可能なエラー)した場合
- 事前条件を満たしており、メソッドの事後条件に処理失敗時のことが規定されている場合
-
TryParse
メソッドのように、「失敗したらfalseを返す」ということが予め表明されている場合がここに該当する
-
例外の指針として、参考になったものリスト
- 「例外は呼び出す側が契約条件を満たしたが、呼び出された側が契約を履行できなかったときに投げるもの」(出典:例外設計における大罪の27ページ目)
- 契約による設計から見た例外
- 再度、契約による設計と例外について
- Java/Androidにおける例外設計、あるいは「契約による設計」によるシンプルさの追求