CODE COMPLETE 上 - 第5章まで

3 月から「1 ヶ月 1 技術書読破」縛りを実施中なので、頭の整理も兼ねて自分用にメモ。

3 月の課題本は表題の通り。4 月の課題本までは読みきってるけどアウトプットが追いついてない。インプットに偏るのよくないのでペース上げていきたい。

600 ページくらいあって内容はもりもりなので、今回は設計までに絞って整理。ただ、整理するだけで消化できる類のものではないので、これからも何度か重ね読みしながら現場で実践していかないとあかんなあと思った。

コンストラクションに入る前の話

コンストラクションの準備における最大目標は、リスクを削減することである。

  • 要するに、最初が肝心だということ
  • プログラマはソフトウェアの食物連鎖の末端にいるので、コンストラクションに入る前の上流の作業がきちんとできてないとそもそもどうしようもない

課題定義

課題定義は、ソリューションとして考えられるものに一切言及せずに、課題が何であるのかを定義するものだ。

  • 課題:システムが解決するもの
  • 専門的な用語を使用せず、ユーザーの言葉で語られるべき
  • 最良のソリューションがコンピュータプログラムではないかもしれないということも頭に入れておく

要求定義

明確な要求は、システムの機能をプログラマではなくユーザー主導で決定するために役立つ。

  • 課題と同様、ユーザーの言葉で語られるべき
  • プロジェクトに長く従事しプロジェクトに対する理解が深まることで要求は変化するが、コンストラクションよりも後の段階で変化した場合は対応に恐ろしくコストがかかる
  • 要求をビジネス上の価値という観点で評価することを忘れないようにする

アーキテクチャ設計

優れたアーキテクチャはコンストラクションを容易にする。悪いアーキテクチャはコンストラクションをほぼ不可能にする。

  • アーキテクチャ設計などの上流の作業は専門知識を持った人がやらないとダメで、専門知識のない人が時間かけても意味がない
  • システムをサブシステムに分割し、サブシステムの独立性を高くすることで、頭の負担が軽くなる(人間の限界を心得て、1 つの単純な問題に集中できるように複雑な問題を分割する)
  • エラー処理の影響はシステム全体に波及するから、アーキテクチャレベルで扱った方がよい

プログラミングを成功させる鍵は、自由裁量によるばらつきをなくし、ばらついていて当然の部分に思考を集中できるようにすることだ。

コンストラクションにおける設計

すべてのソフトウェア設計手法の目標は、複雑な問題を単純な問題に分割することである。

クラスやルーチンは、複雑さを軽減するときに真っ先に思い浮かぶツールである。それらを使って作業を単純化できないとしたら、それらは目的を果たしていない。

最初に思い付いた設計が十分に良さそうに見えたとしても、そこでやめてはならない。ほぼ必ずと言っていいほど、2 回目の設計の方が 1 回目よりもうまくいく。

以下、いろいろ書いてるけど、とにかく「単純にすること」にこだわる。

設計に望ましい特性

  • 最小限の複雑さ
  • 保守性
  • 疎結合
  • 拡張性
  • 再利用性
  • 高いファンイン(1 つのクラスを使用するクラスの数を多くすること)
  • 低いファンアウト(1 つのクラスが使用する他のクラスの数を少なくすること)
  • 移植性
  • 無駄のなさ
  • 階層化

設計に関するヒューリスティクス

設計はヒューリスティックな作業である。1 つの手法に固執すると、創造性が失われ、プログラムも悪い影響を受ける。

クラス設計のところの方が具体的な話が出てくるので、詳細はそこをまとめるときに。ここでは印象に残った 3 つについて簡単にまとめる。

首尾一貫した抽象化を目指す

  • 「首尾一貫した」

秘密を隠す(情報隠ぺい)

情報隠ぺいの「秘密」は、大きく 2 種類に分類される。
■ 複雑さを隠ぺいして、特に必要がなければ考えずに済むようにする。
■ 変更の源を隠ぺいして、変更が発生したときに、その影響を 1 か所にとどめる。

  • 複雑さの隠ぺい
  • 何を隠ぺいすべきか自問する習慣をつける
  • 変更の可能性が高い領域を特定し、適切に隠ぺいする
  • 設計段階で情報隠ぺいによるパフォーマンスの低下を心配するのは時期尚早

システムのパフォーマンスを測定し、ボトルネックを突き止めるまでは、コードレベルのパフォーマンスを向上するために最良の方法は、モジュール性の高い設計を行うことである。そうすれば、ホットスポットを突き止めたときに、システムの残りの部分に影響を与えずに、個々のクラスやルーチンを最適化できる。

モジュール間結合は疎結合にする

  • ルーチンの中で何が起きているのかを知っていないとルーチンに渡さなければならない引数を用意できないようではダメ

まとめ

  • コンストラクションに入る前に上流の作業(課題定義・要求定義・アーキテクチャ設計)をきちんとやる
  • 設計では、複雑な問題を単純にすることにこだわり、ヒューリスティクスを積極的に利用する

次回

最も学びがあったクラス設計の話をまとめたい。

comments powered by Disqus