勉強日記

チラ裏

Clean Code ch7 Error Handling

www.oreilly.com


Error Handling

  • エラーハンドリングは重要
  • だが、エラーハンドリングで散らかって、ロジックの理解が困難になりがち
  • 本章ではクリーンで堅牢なコードを書くためのテクニックを紹介する

Use Exception Rather Than Return Codes

  • 例外機構がなかったのは遠い昔の話
  • 当時はエラーハンドリング・レポート方法は限られていた
    • ラーフラグをセットする
    • エラーコードを返す
  • これらの方法では、呼び出し側がその場ですぐにチェックしなければならない
    • ロジックが散らかる
    • チェックし忘れる
      • 【補】printfの戻り値をちゃんとチェックする人が何人いますか?みたいな話
  • 例外を投げよう
    • 離れたところでチェックできる
    • 関心の分離
      • ロジック
      • エラーハンドリング

Write Your Try-Catch-Finally Statement First

  • 例外機構はスコープを定義する
  • トランザクションのようなもの
    • tryブロック中の任意の場所で処理が中断されうる
    • 中断された場合、catchブロックから処理が再開する
    • catchブロックがconsistencyを担保する
  • 例外を投げうるコードを書くときは、(中身ではなく)try-catch-finallyステートメントから書き始めよう
    • tryブロック中で例外が発生したとき、利用側が何を期待すべきかをまず決める
  • TDD的には、まず「例外が投げられる」テストケースから書き始める
    • red: 例外を投げないstub実装
    • green: 例外を投げる実装
    • refactoring: 例外の型を縮小するなど
      • ExceptionからFileNotFoundExceptionにするとか
  • その後でtryの中身を作っていく
    • 普段通りのTDD
    • さも例外が発生しえないかのように扱える

Use Unchecked Exceptions

  • 検査例外
    • Javaの最初のバージョンで導入され、素晴らしいアイデア…だと思われていたもの
    • メソッドのシグネチャに例外を含める
  • 本当に「値段に見合う価値」があるのか?
  • 検査例外における「値段」とは何か
  • OCP違反
    • 下位モジュールが検査例外を投げるように変更したとする
    • catchされるまでの上位のモジュールすべてが影響を受ける
      • throws句の追加・再デプロイ
    • 例外機構の本末転倒
      • 呼び出し側がその場ですぐチェックしなくて済むように導入したはずなのに
  • 検査例外は、クリティカルなライブラリを書くうえで有用なこともある
  • が、一般的なアプリケーション開発では依存のコストのほうが高くつく

Provide Context With Exception

  • 例外に情報を詰めよう
    • エラー発生源・場所
    • 失敗した操作の意図
    • 失敗の種類
    • catchブロックでログ出力できうる十分な情報

Define Exception Classes in Terms of a Caller's Needs

  • catch側のことを考えて例外を分類しよう
  • あるものをcatchして別のものを素通りさせたい、というときにだけ例外クラスを分けよう

Define the Normal Flow

  • 必要に応じてSpecial Caseを使おう
    • PofEAAのやつ
    • 【補】NullObjectはSpecial Caseの特別なケース(special case)

Don't Return Null

  • nullチェックまみれになる
  • 一つ忘れるとNullPointerException
  • 代わりに例外を投げるか、空のリスト、NullObjectなどを返そう
  • 【補】Maybe, Eitherモナドなんかもあるわね
    • パターンマッチがないと辛い

Don't Pass Null

  • メソッドにnullを渡すのは、nullを返すよりももっと悪い
  • 渡された側はどうする
    • 何もしない
    • nullチェックしてInvalidArgumentExceptionを投げる
      • NullPointerExceptionよりは幾分マシ
      • だが、InvalidArgumentExceptionのハンドラが必要
        • 捕まえてどうするの?
    • 非nullアサート
  • nullを渡すのを禁止するのが吉
  • 【補】「参照型でもnullを禁止してくれる」言語だと考えなくていいので嬉しいですね
    • C#8.0の目玉機能