なになれ

IT系のことを記録していきます

A Philosophy of Software Designの19章要約

本内容は「A Philosophy of Software Design」の19章を要約する記事です。

過去記事

18章の紹介

他担当の方が要約した18章の内容を引用します。

  • 18章 コードは明白であるべき
  • 不明瞭性は、システムに関する重要な情報が新しい開発者にとって明白でない場合に発生する
    • 不明瞭さの問題の解決策は、コードが明白になるように書くこと
  • この章では、コードを明白にする、または明白でなくする要因のいくつかを説明する
  • "自明 "とは読む人の心の中にあるものです。自分のコードの問題点に気づくより、他人のコードが自明でないことに気づく方が簡単です。したがって、コードの自明性を判断する最良の方法は、コードレビューを通じて行うこと
    • もし、あなたのコードを読んだ誰かが自明でないと言ったら、あなたにはどんなに明確に見えても、それは自明ではない
  • コードを明白にするための最も重要な2つのテクニックとして
    • 1つ目は、良い名前を選ぶことです(第14章)
      • 正確で意味のある名前は、コードの振る舞いを明確にし、ドキュメントの必要性を低減する
    • 2つ目のテクニックは「一貫性」(第17章)
      • 同じようなことがいつも同じような方法で行われていれば、読者は以前見たことのあるパターンを認識し、コードを詳しく分析しなくてもすぐに(安全な)結論を導き出すことができる
  • その他のテクニック
    • 空白をうまく利用する
      • コードの書式は、コードの理解しやすさに影響を与えることがある
      • この方法は、各空白行の後の最初の行が、次のコードブロックを説明するコメントである場合に特に効果的:空白行は、コメントをより見やすくする
  • コードを非自明化するものはたくさんある
    • イベントドリブンプログラミング
      • イベントドリブンプログラミングでは、制御の流れを追うことが難しくなります。イベントハンドラ関数は直接呼び出されることはなく、イベントモジュールによって間接的に呼び出されます
      • 不明瞭さを補うために、各ハンドラ関数のインターフェイスコメントを使用して、それがいつ呼び出されるかを示すようにする
  • Redflag: Nonobvious Code
    • コードの意味や動作が、ぱっと読んだだけでは理解できない場合は、赤信号です。多くの場合、これは、コードを読んだ人がすぐに理解できない重要な情報があることを意味します
    • 多くの言語では、JavaのPairやCのstd::pairのように、2つ以上の項目を1つのオブジェクトにまとめるための汎用クラスが提供されている
    • 汎用コンテナは、グループ化した要素の意味が不明瞭な汎用名を持っているので、明白ではないコードになってしまう
      • コンテナが必要なら、特定の用途に特化した新しいクラスや構造体を定義してください。そうすれば、要素に意味のある名前を使うことができますし、汎用コンテナでは不可能な追加ドキュメントを宣言で提供することができます
        • 一般的なコンテナは、コードを書く人にとっては便利ですが、後に続くすべての読者にとって混乱を引き起す。コードを書く人にとっては、数分余計に時間をかけて特定のコンテナ構造を定義した方が、出来上がったコードがより明白になる
  • 自明性について考えるもう一つの方法は、情報という観点
  • コードを明白にするためには、読者がコードを理解するために必要な情報を常に持っているようにしなければならない
    • 一番良い方法は、抽象化や特殊なケースの排除などの設計テクニックを使って、必要な情報の量を減らすこと
    • 第二に、読者が他の文脈で既に習得している情報(例えば、慣習に従う、期待に沿うなど)を利用し、読者があなたのコードのために新しい情報を習得する必要がないようにすること
    • 第三に、良い名前や戦略的なコメントなどのテクニックを使って、コードの中で重要な情報を読者に提示すること

19章の要約

  • 19章 ソフトウェアの動向
  • 概要
    • 過去数十年の間にソフトウェア開発のトレンドと本書の原則との関係を説明する
    • ソフトウェアの複雑性に対するレバレッジを提供するかどうか原則を使用して評価する
  • オブジェクト指向プログラミングと継承
    • インタフェース継承
      • 同じインタフェースを複数の目的で再利用することで複雑性に対するレバレッジを提供する
    • 実装継承
      • 使用には注意が必要
      • 親クラスの下にあるクラス階層全体を把握しなければ変更できない可能性がある
      • 継承ではなく、委譲が使えないかを検討する
    • オブジェクト指向プログラミングはクリーンな設計の実装に役立つが、良い設計を保証するわけではない
  • アジャイル開発
    • 1章で述べたインクリメンタルアプローチに似ている
    • 戦術的なプログラミングにつながる可能性がある
    • アジャイル開発はできるだけ早く実用的なソフトウェアを作るために設計の決定を先延ばしにすることを奨励する
  • ユニットテスト
  • テスト駆動開発
    • テスト駆動開発の問題点は、最適な設計を見つけることよりも、特定の機能を動作させることに注意を集中させること
    • これは戦術的なプログラミングである
    • 設計を行うための明確なタイミングがないため、混乱した状態で終わる
    • 開発の単位は機能ではなく、抽象化であるべき
    • テストを最初に書くことが理にかなっているのは、バグを修正するとき
  • デザインパターン
  • getterとsetter
    • インスタンス変数の公開は、クラスの実装の一部が外部に見えてしまうことを意味し、 情報隠蔽の考え方に反し、クラスのインターフェイスを複雑化させる
    • getterやsetter(あるいは実装データの公開)は、できるだけ避ける
  • 結論
    • 新しいソフトウェア開発パラダイムに出会ったときはいつでも複雑性の観点から評価する
    • それらのいくつかは複雑さを改善するのではなく、悪化させることもある

感想