アルパカログ

Webエンジニア兼マネージャーがプログラミングやマネジメント、読んだ本のまとめを中心に書いてます。

防御的プログラミングと例外「CODE COMPLETE」まとめ

前回のエントリでは名付け、継承、凝集度などをまとめた。

このエントリでは、「CODE COMPLETE」から防御的プログラミングと例外、変数についてまとめる。

防御的プログラミング

「防御的プログラミング」とは、プログラミングに対して防御的になること、つまり「そうなるはずだ」と決め付けないことである。

  • garbage in, garbage out
    • ゴミを入れるとゴミしか出ない
    • プログラムへの入力を誤れば、プログラムは正しく応答しない
  • 外部ソースからのデータの値をすべて確認する
    • 許容範囲内に収まっていることを確認する
  • 関数のすべての引数の値を確認する
  • 入力データは入力されたときに正しい型に変換する
  • あまりに防御的なプログラミングも、それはそれで問題である

正当性と堅牢性

  • 正当性とは、不正確な結果を返さないこと
  • 堅牢性とは、ソフトウェアの実行を継続できること

通常は、動かないプログラムの方が欠陥があるプログラムよりも被害がずっと少ない。

例外

  • 例外は、使いようによっては複雑さを軽減できるが、軽率な使い方をするとコードを理解できなくしてしまう
    • この点は継承と同じ
  • 例外はカプセル化を弱め、コードの複雑さを増大し、プログラマの責務である「複雑さへの対応」にマイナスに働く
  • 呼び出し元に例外を渡す場合は、例外の抽象化レベルがインターフェイスの抽象化レベルと一致していなくてはならない

悪い例

Public TaxId GetTaxId() throws EOFException {
  ...
}

良い例

public TaxId GetTaxId throws EmployeeDataNotAvailable {
  ...
}

EOFExceptionEmployeeDataNotAvaileble にマッピングしただけかもしれないが、インターフェイスの抽象化レベルは維持できている。

  • 例外メッセージに例外の原因に関するすべての情報を盛り込む
  • 空の catch ブロックを書かない
    • 空の catch ブロックを書く場合は、なぜ空のままで良いのかを文書化する
  • ライブラリがスローする例外を知る
  • プロジェクトで例外の使用法を標準化する
  • プロジェクト固有の例外クラスの作成を検討する
    • プロジェクトでスローされる例外の基底クラス
    • ログの記録やエラー報告などの一元化に役立つ

変数

変数の良し悪しはその名前でだいたい決まってしまう。変数名は慎重に選択すべし。

  • 変数は1つの目的にのみ使用する
  • 変数に二重の意味を持たせない
    • 変数にどちらかの用途にふさわしくない名前が付いているか、両方に「一時的な」変数(xやtempといった名前)が使われているかのどちらか
    • このような変数の乱用を「ハイブリッド結合」という
  • 状態変数には flag よりも良い名前を付ける
  • 一時変数はプログラマが問題を十分に理解していない証拠である
    • 一時的なものであるということから、プログラマがそれらを他の変数よりも軽く扱うようになり、エラーの可能性が高まる
  • 変数の良し悪しはその名前でだいたい決まる
  • 良い名前は、方法(how)ではなくもの(what)を表すことが多い
  • 意味は異なるが似ている名前を使わない
    • 類似度を「心理的距離」という
  • 変数名に数字を使わない
    • 名前に含まれる数字が重要なら配列を使用する
    • 例えば Route60 のように数字が意味を持つものは例外
  • 名前を付ける際には書き手よりも読み手の便宜を優先する
  • 名前の綴りを故意に変えない
    • highlight → hilite
    • 何文字か短縮できたとしても、読み手にとっては別の綴りを覚えろと言われたようなもの
  • 複数の自然言語を組み合わせない
    • 特に英語は注意
    • color か colour か、check か cheque か
  • 予約語は避ける
  • 変数に短い名前を付けると、長さそのものが限られたスコープを持つ変数であることを示す
    • i など
  • Total, Sum, Average, Max, Min, Record, String, Pointer といった修飾子は名前の最後に付ける
    • RevenueTotal など
    • Num だけは例外
    • Num を先頭に付けると合計を意味する
      • numCustomers は顧客の総数を表す
    • 末尾に付けるとインデックスを意味する
    • Num は混乱のもとなので使用を避ける
      • 総数を表すには Count または Total
      • インデックスを表すには Index
  • ブール変数には真または偽を意味する名前を付ける
    • status や sourceFile といった名前は真偽を表さない
  • 肯定的なブール変数名を使用する

一般的なブール変数名

  • done
    • 何かが完了したことを表すために使用する
    • 処理が完了する前に false に設定し、完了したら true に設定する
  • error
    • エラーが発生したことを表すために使用する
  • found
    • 値が検出されたことを示すために使用する
  • success
    • 処理が成功したことを表すために使用する

定数名

  • 定数が参照する数値ではなく、定数が表す抽象的なエンティティに名前を付ける
    • FIVE はたとえ値が5.0だとしてもふさわしくない
    • CICLES_NEEDED は良い

省略形

  • 変数名を短くしたいと思うのは、初期のコンピューティングの名残である
    • アセンブラや古い言語(FORTRANなど)では変数名が2~8文字に制限されていた
  • 現代の言語では名前の長さにほとんど制限がないのでわざわざ短くする必要はない

おわりに

このエントリでは、「CODE COMPLETE」の防御的プログラミングと例外、変数についてまとめた。

参考になった方は、ぜひ「はてブ」やSNSでシェアしていただければ幸いである。

「CODE COMPLETE」の他の章は下記でまとめている。