読書メモ:プリンシプル・オブ・プログラミング - 3年目までに身につけたい一生役立つ101の原理原則

読書メモ:プリンシプル・オブ・プログラミング - 3年目までに身につけたい一生役立つ101の原理原則

July 12, 2023

以下の本を読んだ。記憶しておきたいところについてメモを残しておく。

以前に購入してから年単位で積読状態にあったもの。本棚の整理にあたり今回ようやく目を通した。本書は、プログラミングにおける用語・格言やセオリーの紹介と、それが我々に伝えようとしていることを説明したものである。初めて目にするようなものはほとんどなかったが、そのなかでも時折り見返したい内容をここに書き留めておくことで読書記録とする。


契約プログラミング(契約による設計、Design by Contract、DbC) #

「呼び出し側」と「呼び出される側」の取り決め

関数はそれぞれ「何らかの作業」を行うもの。その「何か」を開始する前に、その世界について何らかの「想定」を置き、終了時にその世界についての何らかの「確約」を行うことができるはず。この「想定」が「事前条件」で、これは「関数が呼び出す側が守るべき契約」である。一方、「確約」は「事後条件」で、これは「関数が守るべき契約」である。このように「呼び出し側」と「呼び出される側」で、互いに「契約」を結んでいると見なしてプログラミングすることを、「契約による設計」と言う。

「契約による設計」においては、契約に従い、関数を呼び出す側は、関数の呼び出し前に「事前条件」を満たすようにする。正しい引数を渡すのは、関数を呼び出す側の責任である。一方、呼び出される側は関数の最後に「事後条件」を満たすようにします。関数呼び出し後に保証されるべき内容を充足するのは、関数を呼び出される側の責任である。

いずれかの契約条項を履行できなかった場合は、例外を送出することでその契約を終了する。

コメントとアサーションで契約

契約の内容は関数のコメントで伝える。そして契約履行のチェックのためのコードは、アサーションで表現する。

  • 注意点
    • 関数側では引数の調整を行わないこと:呼び出される関数の側で、渡された引数の調整をしてはいけない。たとえば、本来は契約外の引数が渡ってきたときに、親切にも関数側でそれを事前条件に適するように調整を行ってはならない。それは関数を呼び出す側の責任である。呼び出される側は、契約に基づいて安心して引数を使うべきであり、結果コードをシンプルに保つことができる。
    • 関数側のアサーションをユーザの入力チェックに使用しないこと:事前条件はあくまで「関数を呼び出す側」と「呼び出される側の関数」の契約であって、「関数」と「ユーザー入力」の契約ではない。契約の不履行とは起こってはならないことであり、ユーザーの入力ミスとは質の異なる事象であり、これらを混同してはいけない。ユーザの入力チェックは、関数を呼び出す前に、関数を呼び出す側で行うべきことである。
    • 想定は厳格にすること:何でも受け付け、どんな時でも結果を保証するとしたらその実現には大量のコード記述が必要になる。そうならないよう、事前条件は厳格に絞り込むこと。書くコードはなるべく少なくするように努める。

ブルックスの法則 #

要員追加は「火に油」

進捗が遅れているソフトウェア開発プロジェクトにおいて、遅れを取り戻すために人を追加しても、逆にさらなる遅延を招く。素直にリスケジュールせよ。

「人」と「月」は交換不可能

プロジェクトの工数は人月換算される。何人が、何ヶ月従事するかで、「人 × 月」の掛け算になる。しかし単純な数値の掛け算とはことなり、「人」と「月」は交換可能ではなく、「人 × 月 = 月 × 人」の式は成り立たない。2名で6ヶ月開発するのと、6名で2ヶ月開発するのでは、実際の能率は大きく異なる。その理由は次の通りである。

  • 人数が増えるに従ってオーバーヘッドが増加する:コミュニケーションコストやタスクの分割のコスト、各結果の確認や統合のコストが増加する。
  • 教育の時間が必要となる:新規追加のメンバーが戦力になるまでには、プロジェクト固有の知識が必要になる。その教育をするのは既存メンバーであり、その間、組織としての生産性は大きく低下する。

生産と出産のアナロジー

妊婦を 10 人集めても、1ヶ月で赤ちゃんを出産することはできない。生産性は単なる労働力の足し算ではないということがよく分かる比喩である。

コンウェイの法則 #

アーキテクチャは組織に従う

ソフトウェアの構造、つまり「アーキテクチャ」は、それを作った「組織」を反映する。例えば3つのチーム編成で何かを作れば、そのシステムは3つのモジュールから構成されるように形作られるだろう。

アーキテクチャはコミュニケーションに従う

ソフトウェアを設計する組織は、その情報伝達の構造を真似た設計を生み出す傾向にある。これは、組織構造に従ってコミュニケーションが構築され、そのコミュニケーションに沿ってアーキテクチャが構築されているためである。結果として、ソフトウェアのアーキテクチャは、組織のコミュニケーションパスによって形作られることになる。

アーキテクチャ設計後に組織編成せよ

自然に任せると、アーキテクチャは組織に従うが、理想はむしろその逆だ。組織の都合でできたアーキテクチャが、ソフトウェアの観点から見て最適なはずはない。まずは求めるアーキテクチャがあって、それを実現する組織を編成するべきである。

組織とプロセス

「組織」と「アーキテクチャ」だけでなく、「組織」と「プロセス」の相性も考慮すること。例えば「メインフレームチーム」、「データベースチーム」、「Web サーバチーム」、「テストチーム」と技術分野で組織編成を行った場合、アジャイル開発では苦労することが容易に予想できる。それぞれのチームはどの機能の実現においても単独では完了できず、他のチームの協力を必要としてしまう。たとえ小さな機能ですらも、その開発には大量のチーム間コミュニケーションが必要となり、コストがかかってしまう。「組織」「アーキテクチャ」「プロセス」は密接に関わるため、注意深く模索しなければならない。