A Philosophy of Software Design ch13 Comments Should Describe Things That Aren't Obvious From The Code
Comments Should Describe Things That Aren't Obvious From The Code
- コメントを書く理由
- プログラムコードには、開発者が念頭においていた重要な情報全てを込めることはできない
- コメントで残しておき、将来簡単にコードを理解・変更できるようにする
- コメントには(隣の)コードから明白でないことを書け
- コードよりも低水準の詳細
- なぜそのコードが必要なのか
- 事前条件
- 「必ずbの前にaを呼べ」
- コードをしらみつぶしに読めば推測できるが、苦痛で間違いも起きやすい
- コメントを書く最も重要な理由は、抽象化
- 本章のテーマ
- コメントには何が記述されるべきか
- 良いコメントを書く方法
- 良いコメントは、コードとは異なる詳細度である
- コードよりも詳細
- コードよりも抽象的
Pick conventions
- コメントの規約を決める
- フォーマットを決める理由
- 一貫性
- 読みやすく理解しやすい
- 書きやすくもなる
- 何をどうコメントすればよいかの枠組み
- 【補】PHPDocの
@param
とか@return
とか
- 【補】PHPDocの
- 何をどうコメントすればよいかの枠組み
- 一貫性
- コメントの分類
- インタフェース
- モジュール直上のコメント
- クラス
- データ構造
- 関数
- メソッド
- モジュールのインタフェース
- クラス
- 全体的な抽象化
- 関数やメソッド
- 全体的な振る舞い
- 引数
- 戻り値
- (あれば)副作用
- (あれば)例外
- 事前条件
- クラス
- モジュール直上のコメント
- メンバのデータ構造
- インスタンスメンバ変数
- クラスメンバ変数
- 実装
- メソッドや関数内のコードに添える
- モジュール横断
- モジュール間の依存についてのコメント
- インタフェース
- はじめの2つが最重要
- 実装コメントは必要ないこと多し
- モジュール横断的なコメントは最もまれだが…
- 書くうえで厄介
- 必要な場合はとても重要
Don't repeat the code
- コードのオウム返しのコメントはなんの付加価値もない
- 「コメントは無価値」と考える開発者もいる理由がこれ
- 説明しようとしているものとは異なる単語で書け
/** * The horizontal padding of each line in the text. */ private static final int textHorizontalPading = 4;
- 問題点
- そもそもパディングって何?
- パディングはどこにつくの?
- パディングの単位は?
/** * The amount of blank space to leave on the left and * right sides of each line of text, in pixels. */ private static final int textHorizontalPading = 4;
- 改善した点
- パディングなるものの説明
- パディングがつく場所の明示
- パディングの単位の明示
Lower-level comments add precision
- コメントは、コードと異なる詳細度の知識でコードを補強する
- コードよりも低水準で詳細なコメントは、精度を加える
- コードよりも高水準で抽象的なコメントは、直感性を提供する
- コードと同じ詳細度のコメントは、コードのオウム返しになりがち
- 本節では「コードよりも低水準のコメント」について述べる
- コードよりも低水準のコメントが有用なのは:
- メンバ変数
- メソッド引数
- メソッド戻り値
- 変数宣言中の名前と型は精度が不十分であることが多い
- 【補】PHPでは配列の要素型を表現できなかったりする
- コメントが補いうる情報
- 変数の単位
- 境界を含むか含まないか
- 【補】ある程度は名前の規約で表せる
- endは含まない
- lastは含む
- 【補】ある程度は名前の規約で表せる
- nullの意味
- リソースの解放は誰の責任か
- 不変条件
- 例: 「コレクションの要素数は最低でも1」
- コードをしらみつぶしに読めば理解できるが、時間がかかるし間違いも起きやすい
// Contains all line-widths inside the document and // number of appearances private TreeMap<Integer, Integer> lineWidth
// Holds statistics about line lengths of the form <length, count> // where length is the number of characters in a line // (including the newline), and count is the number of lines with // exactly that many characters. If there are no line with // a particular length, then there is no entry for that length. private TreeMap<Integer, Integer> numLinesWithLength;
- 改善した点
- 文字列長 => 度数 なる度数表であることがわかる
- 「width」ではなく「length」という語を採用したことで、単位が「文字数」であることが伝わりやすくなった
- エントリがないことの意味の説明が追加された
Higher-level comments enhance intuition
- 本節では「コードよりも高水準のコメント」について述べる
- 直感的なわかりやすさを提供する
- (長いわりに大したこと言ってないので省略)
- 高水準なコメントは、低水準なコメントよりも書くのが難しい
- 自問せよ:
- このコードは何をしようとしているか?
- コードのすべてを説明するもっとも単純なものは?
- このコードで最も重要なことは?
- 自問せよ:
- whatのほか、whyを書く
- なぜそのコードが実行されるのか
- どういう条件下でそれが実行されるのか書くと有用
- 異常系でのみ実行される場合とくに
Interface documentation
- コードは詳細すぎて、インタフェースに含めるべきでない情報を含んでしまう
- よい抽象化のためにはコメント必須
- インタフェースコメントと実装コメントとを分離する
- インタフェースコメントが実装についても述べているならば、そのクラスもしくはメソッドは浅いということ
- 書くべき内容
- 呼び出し元から見た振る舞い
- 冒頭1-2文程度
- 引数と戻り値
- これは低水準のコメントであること
- 引数の制約条件についても記述する
- 引数間の依存関係等
- 副作用
- 例外
- 事前条件
- 例: 2分探索に渡すコレクションはソート済でなければならない
- 制限
- マルチスレッドで使えない旨など
- 利用者にとって、このモジュールを利用するか否かの判断材料になる
- 呼び出し元から見た振る舞い
- 書くべきでない内容
- モジュールを利用するにあたり知る必要のない実装の詳細
- private定数の設定
- モジュール実装者向けコメントであって、モジュール利用者向けではない
- 内部で握りつぶす例外フロー
- 【補】define errors out of existence にも通ずる話
- (同じことをずっと書いてる)
Implementation comments: what and why, not how
- コードが何をしているかの理解を助ける
- どのようにしているか、ではなく
- 何をしているかわかれば、どのようにしているかも追いやすくなる
- 1つのことだけをする短いメソッドでは不要
- インタフェースコメントにすでに書いてあるはず
- 行っていることが複数フェーズに別れるような場合に書く
- 【補】テストスイートで 準備、アクション、アサート、後始末各フェーズにコメントを書く
- 長いメソッドでは、重要な局所変数にコメントを書くと有用なことがある
- たいてい良い名前をつければ不要ではある
- その変数が何を表すかを書く
- どう処理されるか、ではなく
Cross-module design decisions
- 理想的には、重要な設計上の意思決定は1クラスの中にカプセル化されているべき
- 実際のシステムでは、設計上の意思決定が複数のクラスにまたがって影響することは避けられない
- 例: ネットワークプロトコルの送信側クラスと受信側クラス
- 良いドキュメンテーションをすることが肝心
- 複雑で捉えづらいことが多い
- したがって、バグの原因となりやすい
- どこに書くか問題
- 開発者が自然に見てくれそうな場所は?
- 良い場所があればそこに
- 良い場所がなければ...
- 著者も模索中の方法: designNoteファイルに集約する
- コードコメントでは、designNoteファイルを参照する
- 欠点: コードから遠く離れてしまう
- 著者も模索中の方法: designNoteファイルに集約する
Conclusion
- コメントの目的は、システムの構造とふるまいを読み手に明瞭に伝えること
- 必要な情報を素早く得られる
- 変更が正しいことの確信を得られる
- コードから明白にわかる情報もあるが、多くはコードから簡単には推測できない
- 隣のコードから明白にわかることをコメントに書かない
- 「明白」というのは読み手の視点
- コメントを書くときには、読み手の立場に立って、必要とする重要な事実は何か自問せよ
- 不明瞭な点をレビューで指摘されても、反論することなかれ
- 何が混乱のもとかを理解し、コメントかコードを改善して明瞭にできないか検討せよ
Answers to questions on page 113
- 実装の詳細は省く
- 利用者が知っている必要のある仕様は書く
- パフォーマンスに関することは必要かも
- 【補】そのモジュールを利用するかどうかの判断材料となる
英語
- distine
- スケジュールする
- contemplate
- 熟考する
- emanate
- 発する
- 例外送出の文脈にて
- 発する