契約による設計の概念を通して、例外の定義や例外処理を確認します
- メソッドの実行時に発生する、メソッドの仕様が満たせなくなるような状態やイベントのこと
An “exception” is an event, which occurs during the execution of a program, that disrupts the normal flow of the program’s instructions.
(The Java™ Tutorial)
- 「例外」とはプログラム実行中に発生するイベントである。そのイベントによってプログラムの命令の通常フローが阻害されます。
- 例外とはメソッド実行中の状態・イベントである
- メソッドの内部動作ではなく、外から見た条件(ふるまいを記述したもの)
- 条件には2種類ある
- 事前条件
- メソッドの実行開始時に満たす条件
- メソッドの呼び出し側に責任がある
- メソッドにとっての利益・信頼していい条件
- 事後条件
- メソッドの実行後に満たす条件
- メソッドが保証する義務がある
- メソッドの呼び出し元にとっての利益(期待している状態)
- 事前条件
- これとは別に事前条件・事後条件には以下の条件が含まれる
- 不変条件(不変表明)
- メソッドをもつオブジェクトが常に満たす条件
- オブジェクトの特性をあらわす
- メソッドの実行開始前、メソッドの実行終了後は必ず満たしている必要がある
- 不変条件(不変表明)
- メソッドの呼び出しは上記の責務
- ビールの販売(1杯
1,000 JPY
)- 事前条件
- 購入する人は 20 歳以上
- 購入する人は運転以外の手段で来場
1,000 JPY
以上のお金を支払う
- 事後条件
- キンキンに冷えたビール(
6 ± 2 ℃
)が渡される - 必要であればお釣りが渡される
- キンキンに冷えたビール(
- 事前条件
- 事前条件・事後条件を満たした状態でメソッドを開始・終了した場合を成功
- メソッドが事前条件を満たした状態で開始される
- 事後条件を満たした状態でメソッドの実行が終了する
- 成功でないものを失敗
- メソッドの失敗につながる実行時に発生する状態・イベントのことを例外
- 依存する(呼び出した)メソッドの失敗は、呼び出し元のメソッドにとっての例外
- 呼び出したメソッドが失敗した状態は、呼び出し元にとって事後条件の達成を阻害するため
- ビールの販売を例にメソッドの成功・失敗を考える
- ビールの販売の事前条件(再掲)
- 購入する人は 20 歳以上
- 購入する人は運転以外の手段で来場
1,000 JPY
以上のお金を支払う
- ビールの販売の事後条件(再掲)
- キンキンに冷えたビール(
6 ± 2 ℃
)が渡される - 必要であればお釣りが渡される
- キンキンに冷えたビール(
- ビールの販売の不変条件
- ビールの販売数 x
1,000 JPY
+
お釣りの準備金=
ビールの売り子が所持している金額
- ビールの販売数 x
- バスで来場した 20 歳以上のお客さんが、
5,000 JPY
を渡して、ビールの売り子にビールを求める(事前条件を満たしたので実行開始)- ビールの売り子がビールをカップに注ぐ
- お釣り入れに
5,000 JPY
をしまい、1,000 JPY
を4
枚取り出す
- ビールの売り子がビールと、お釣りを渡して実行を終了する(事後条件を満たしているので成功)
- 徒歩で来場した 20 歳以上のお客さんが、
1,000 JPY
を渡して、ビールの売り子にビールを求める(事前条件を満たしているので実行開始)- ビールの売り子がビールをカップに注ごうとしたところ、ビールが切れてしまう
- すぐにはビールを調達できないので、諦める
- ビールの売り子が「ビールを切らしてしまいました」と言い、受け取った
1,000 JPY
を返す
- バイクで来場した 18 歳の少年がビールの売り子にビールを求める(事前条件を満たさないので実行開始しない)
- ビールの売り子が「ビールは 20 歳以上になってから」と言い、終了する
- メソッドの事後条件の達成が阻害された状態(例外状態)から、メソッドの実行終了までの制御
- 例外処理には以下が含まれる
- メソッドの成功・失敗を決定する
- 様々な手段を駆使して、事後条件を満たす(リトライ)
- 同じ処理を繰り返す
- 異なる依存オブジェクトを通じて獲得する
- 予め決められたものを適用する(デフォルト値)
- 実行を終了して、失敗を呼び出し元に通知する(失敗/組織的パニック)
- 様々な手段を駆使して、事後条件を満たす(リトライ)
- メソッドの実行によって壊れてしまった不変条件を元に戻す
- メソッドの成功・失敗を決定する
- 徒歩で来場した 20 歳以上のお客さんが、
5,000 JPY
を渡して、ビールの売り子にビールを求める(事前条件を満たしているので実行開始)- ビールの売り子がビールをカップに注ぐ
- お釣りを手にとったところ、お釣りが
3,000 JPY
しかないため、お釣りが用意できない(例外) - 売り子が自分の財布を開けてみたところ、
1,000 JPY
が5
枚入っていることを発見、お客の支払った5,000 JPY
紙幣と交換する
- ビールの売り子がお客さんにビールと、お釣り
4,000 JPY
を渡して実行を終了する
- あるメソッドが失敗で終了した場合、その呼び出し元の例外として現れる
- 呼び出し元がその例外を処理できない場合は、呼び出し元のメソッドが失敗として、さらにその呼び出し元に通知する
- さらにその呼び出し元が例外を処理できない場合は...と例外は上位の呼び出し元に伝播していく
- オブジェクトには特性をあらわす不変条件がある
- メソッドの仕様は事前条件と事後条件で記述できる
- 事前条件を保証するのはメソッドの呼び出し元の責任
- 事後条件・不変条件を保証するのはメソッドの責任
- 事前条件を満たす状態でメソッドが呼び出され、そのメソッドが事後条件を満たして実行を終了することを成功、そうでない場合は失敗
- メソッドの失敗につながる実行時の諸状態が例外
- メソッドの失敗は呼び出し元のメソッドにとっての例外
- 例外処理
- あらゆる方法で事後条件をみたすように回復する(リトライ)
- メソッドの失敗として実行を終了し、呼び出し元に通知する(失敗)