勉強日記

チラ裏

A Philosophy of Software Design ch16 Modifying Existing Code

www.goodreads.com


Modifying Existing Code

  • ソフトウェア開発は反復的でインクリメンタル
    • 設計はたえず進化する
    • 正しい設計を開発の最初から考えることは不可能
      • 最初に考えた分よりも、その後の変更の寄与分のほうが多くなる
  • 本章では、システムが進化するにつれ複雑性が入り込むのを避ける方法について述べる

Stay strategic

  • tactical vs. strategic(ch3.再掲)
  • 既存のコードの変更にもあてはまる
  • 既存のコードの変更時は戦術的になりがち
    • 「要件を満たす最小の変更は?」
      • 大きく変更してバグが追加されるのを恐れてのこと
    • 結果、システムに複雑性が入り込んでしまう
      • 特殊ケース
      • 依存
      • etc.
    • システムが成長するにつれ設計は少しずつ悪化の一途をたどり、問題は蓄積していく
  • 既存のコードの変更においても、設計をきれいに保つには、戦略的姿勢が必要
  • 理想: その変更を予め知っていたら、最初からしていたであろう設計
    • quick fixの誘惑に抗う必要がある
    • 変更のたびに設計を向上させる
  • 投資の姿勢でもある
    • 設計を改善するのにかけた時間は、開発が加速することで取り戻せる
  • コードに変更を加えるときはかならず、少しでもよいので設計の改善につとめよ
    • 設計は良くしない限り、コードに変更加えるたびに悪くなる
  • 0 or 100ではない
    • 現実的に戦略的姿勢をとれないこともある
    • それでもなお、妥協には可能な限り抗うべき
  • 全ての開発組織は、コード掃除とリファクタリング工数を見込むべき
    • 長い目で見てペイする

Maintaining comments: keep the comments near the code

  • コードに変更を加える際、コメントが古くなることがままある
    • 不正確なコメントは読み手を妨げる
    • そういうコメントが多いと、全てのコメントが信用されなくなる
  • 幸い、少しの自律とガイドラインで大きく改善できる
  • コメントを最新に保つには、それが説明しているコードのなるべく近くに置くこと
    • コメントがコードから遠くなるほど更新漏れの可能性が高まる
  • メソッドのインタフェースコメントならば、メソッドの実装のすぐ隣が適している
    • Cの*.hC++*.hppの、宣言の隣に書くべきだよ派
      • モジュール利用者は、実装ファイル(*.c,*.cpp)を開かずともインタフェースコメントを読めるべき
    • 著者による反論
      • 実装に変更を加えた後、コメントを更新するために別のファイルを開かなければならない
      • 利用者はそもそも*.c*.hも読むべきではない
        • DoxygenJavadocで自動生成したドキュメントを読むべき
        • IDEの機能によって、メソッド名をタイプした際にインタフェースコメントを抽出して表示してくれたりもする
  • 詳細な実装コメントはメソッド冒頭にまとめない
    • 処理が複数フェーズに分かれているなら、各フェーズ冒頭に置く
  • 処理の概略をメソッド冒頭にまとめるのは有用
// We proceed in three phases:
// Phase 1: Find feasible candidates
// Phase 2: Assign each candidate a score
// Phase 3: Choose the best, and remove it
  • 一般に、コメントはコードから離れるほど抽象度を上げるべき
    • コメントが腐る可能性を下げる

Comments belong in the code, not the commit logbook

  • ドキュメンテーションは、開発者がもっとも見そうな場所に配置する
  • コミットログが適所であることはまれ
  • 例: 厄介な問題に対処するためのコード変更
    • そのことをコメントに書いておかないと、将来変更が巻き戻され、同じバグが再発する可能性がある

Maintaining comments: avoid duplication

  • さもないと更新が大変
  • 設計上の意思決定ひとつにつき1つのコメントを心がけること
    • 複数箇所に影響している場合は、最も明白な一箇所に記述する
      • 変数の利用方法ならば、変数定義の真上
    • そういう場所がなければ、designNotesファイルに集約し、参照する
      • 参照先が移動したり削除されたりしたら、情報が古くなったことがすぐわかる
      • 参照せずにコピペしてしまうと、情報が古くなっても気づけない
  • あるモジュールの設計の意思決定を、別のモジュールの中に書かないこと
    • 「このメソッドを呼ぶと何が起こります」というのを呼び出し側に書かない
  • コード外で資料化されている情報をコード中で繰り返すな、参照せよ
    • HTTP実装クラスならば、HTTPの仕様を書かず、Web上の情報源のURLを載せる
    • ユーザマニュアルに載っていることならば、「マニュアル参照のこと」とコメントする
  • 読み手が必要な情報を簡単に得られることが重要なのであって、全てを書く必要はない

Maintaining: check the diffs

  • コミット前に数分程度かけて差分をチェックする
    • 変更がコメントに反映されているか
  • 別の問題も検出できる

Higher-lovel comments are easier to maintain

  • 詳細で正確なコメントが必要なこともある
  • が、総じて、実装よりも高水準で抽象的なコメントが、有用かつ保守もしやすい
    • 実装の繰り返しでない
    • ので、実装に多少の変更があっても影響をうけない
    • 全体的な振る舞いが変わるときのみコメントに変更が必要になる

英語

  • recoup
    • 取り戻す、埋め合わす