『人月の神話 』と「銀の弾などない」

ソフトウェア工学(エンジニアリング)は、電気工学のように「精密で包括的な数学的基礎」を持ったエンジニアリング分野なのか?

ソフトウェア工学は、経営工学と同じように人間の行動の複雑性によって永久的に混乱させられていて、未熟で、それはまるでタールの沼だと、著者のフレデリック・P・ブルックス,Jr.は言う。

ブルックスの代表著作人月の神話 20周年記念増訂版 【新装版】 は、「人月の神話(1975年)」に加え「銀の弾などない(1986年)」、及びその2編を20年後、9年後に振り返って補足追加する文章を含んだ、ソフトウェア工学の古典的名著だ。

発表から35〜45年経過しているため、登場する技術(IBM OS/360、Ada、etc)や環境(メモリ、保存領域の制限等)は古く、現代の技術・環境との乖離は否めない。

しかしこの本は時代を超えて,ソフトウェア制作現場の息づかいや、苦悩、そしてその先にあって欲しい「光」についてのヒントをたくさん与えてくれる。

プログラミングシステム製品とは

ブルックスは最初に、本書が取り扱う「プログラミングシステム製品」を以下のようなステップで定義する。

  • 「プログラム」とは、ガレージで生み出される類いの、アイデアをコード実装したほかほかの状態を指す。

  • 「プログラミング製品」は、「プログラム」の入力の範囲・形式が、基本的アルゴリズムで妥当であると認められるくらいまで一般化され、誰もが信頼性の高いテストで検証でき、ドキュメントに従い修正・拡張可能なものだ。これは同等の機能を持つデバッグ済みプログラムの最低3倍のコストがかかるという。

  • 「プログラミングシステム(のコンポーネント)」は、入出力が的確に定義されたインターフェースを持つ構文およびコマンドの語義に準拠するように書かれており、メモリスペースや入出力装置、コンピュータ時間といったリソースを定められた量だけ使用するようにデザインされている状態だ。他のシステムコンポーネントとの予想されるあらゆる組み合わせでテストをする必要があり、同等の機能を持つ単独のプログラムの最低3倍はコストがかかるという。

  • 「プログラミングシステム製品」は、×3×3で「プログラム」の9倍以上のコストを必要とする存在である。

人月の神話

purely programmer

プログラマは、純粋な思考をもってアイデアを実装していく。アイデア自体が間違いだったり、間違って伝わる、齟齬があったりする事が必然なため、バグは生まれる。

バグの発生を予め正確に開発スケジュールに折り込むのは困難だし、バグ以外にも実装上の問題でスケジュールが遅延するのは日常茶飯事だ。

遅延したスケジュールを、人員追加でリカバリーする方法は以下のように3つのオーバーヘッドが生じ、全体の労力を無駄に増大させる。

  1. 再配分作業とそのための中断
  2. 新しい人員の訓練
  3. 新たに必要となる相互コミュニケーション

「遅れているソフトウェアプロジェクトへの要員追加は、さらにプロジェクトを遅らせるだけ」だとブルックスは斬る。「人月」計算は、「人」と「月」が相互に交換可能として扱われがちであり、ブルックスはこれを「人月の神話」と呼び諫めている。

スケジュール遅延が発生した場合は、機能要件を正式に慎重に削減する事が、現実的で一番妥当な方法として本書では紹介されている。

ブルックスが約50年前に考えた全体スケジュール割当

allocating-shedules

ウォーターフォールモデルを前提とした場合、ソフトウェア開発のスケジュールを上記のような比率で配分する事をブルックスは提案している。

コーディングの比率が1/6と小さいことが特徴的だが、IT業界で経験を積んできた方なら、この1/6には納得できるのではないだろうか。計画(設計)に1/3、テストに1/2を割いているのも納得だ。

ただしこれは、ウォーターフォールモデルの場合の話だ。

ブルックスは人月の神話を執筆した20年後に、ウォーターフォールモデルを否定し、漸増的(インクリメンタル)に開発する事を提案している。

約30年前に、アジャイル開発の基礎となるアイデアを発表しているのだ。

機能を1つずつ漸増的に構築してモジュールを追加していく方法で構築すれば、どの段階においても、使える実在システムがある事で、書籍発表当時に提案していた「捨て石」にするだけのプロトタイプを否定している。

表層的なプロトタイプはあっても良いが、漸増的な開発によって常に実在システムで検証が可能であるため、捨て石は不要といっているのだ。

併せて、約30年前、当時のマイクロソフトが始めていた「ナイトビルド(毎晩構築)」についても言及している。これは、昨今のDevOpsに繋がる考え方だ。

スケジュール管理とマイルストン

大規模プロジェクトをコントロールするには、まずマイルストーンとその日付で構成されたスケジュール表を用意する必要がある。そしてマイルストンの完了定義は、スタッフが誰も言い訳できないような明快なものにすべきだと言う。

また、スケジュール表をつくる上では、PERTやクリティカルパススケジューリングの作成の重要性を訴える。作業の依存関係による、最短スケジュール(最長ルートを通る依存関係パスルートの日数)を把握できるからだ。

スケジュールが遅延した場合にも、PERTやクリティカルパスを影響分析に活用すれば、リカバリープランを考える上の重要な指標となりうる。

外科手術チーム

プログラマーの生産性は、同じトレーニングを2年受けた状態で、10倍の差が出るという研究結果があるという。

そのため、10人程度の開発チームを組織する場合は中央集権的な専門家チームを編成する事でチーム・パフォーマンスが最大化されると言う。

following-chief-programmer.

そしてハーラン・ミルズが発案した「外科手術チーム」を引用し、10人でチームを組織する場合の役割を紹介している。

  • 執刀医(チーフプログラマー): 設計・実装の技術担当であり、全体の責任者。
  • 副執刀医(サブプログラマー): チーフを支援し、必要に応じ義務分担する。
  • 管理者: ボスであるチーフが技術に専念できるよう「お金、人、空間、機械」等を責任を持って管理する。
  • 編集者: プロジェクトの文書化責任者。
  • 秘書(2人): 管理者と編集者を、それぞれ補佐する2人の秘書。
  • プログラム事務: すべてのプロジェクト技術記録を担当。現代はGithubがリプレイスするため不要?
  • ツール技師(Toolsmith):開発で使用するツールの構築、及びサポート。
  • テスター: 仕様からテストケースを作成し、テストデータを用意し、計画的なテスト環境を提供する
  • 言語エキスパート: 執刀医がデザイン(設計)指向なのに対し、言語それ自体に関する深い専門知識を持ち執刀医をサポートする。1人の言語エキスパートが、執刀医2〜3人をバックアップする事が可能。

執刀医、副執刀医は一心同体で、その2人で技術的判断を完結させるため、判断のためのコストが低い。残りのメンバーは、専門的領域で2人に対し「考えられるすべてのサポート」を提供するという役割である。

大規模開発のチーム編成

数年でリリースできるプロジェクト規模であれば少数精鋭でプロジェクトを行うべきだが、少数精鋭で非常に大きなシステムに取り組むと、リリースが遅くなり過ぎ、製品自体の魅力が著しく低下する。

だからといって、やみくもに人を投入していけば非効率でコストが増大に掛かり、コンセプトが統合されていないちぐはぐなソフトウェアが産まれる。ではどうする?

大規模開発の場合、チーム編成で気をつけなければならない点は「必要となるコミュニケーションと調整作業の量を減らすこと」だ。

目的を達成するためには、専門化とその分担の設計が重要である。

とはいえ厳密なツリー構造の編成は、コミュニケーションの実態と乖離する。なぜならコミュニケーションはネットワーク構造でさまざまな階層・部門で行われるからだ。

技術をリードする事と、管理をする事はまったく別の役割で、必要とされる才能も異なるので、技術リードと管理リードの関係性を、チーム編成の際に気をつける必要がある。以下は関係性のパターン例だ。

  • 同一人物が両方を兼ねる場合: 小さなプロジェクトならこれが有効
  • 管理リードがボスで、技術リードがその右腕である場合: 技術リードが管理リードと同等、または上の決定権を持っていると関係者が認識する事が必要。座席配置などステータスシンボルとなるノンバーバルなテクニックを活用する
  • 技術リードがボスで、管理リードがその右腕である場合: 管理リードは、積極的に技術リードの「雑用」をインターセプトして、技術リードが技術に集中できるようにする

例えば200人のチームになったらどうやって「外科手術チーム」を拡大するのが良いだろうか?

200-developers

※この編成案はあくまで自分が作成したもので、本書で紹介されているものではない。

20のプログラミングチームが核となり、それを束ねるCTO/CTO補佐が上に位置する。

共通技術支援部隊として、8名の言語エキスパートが技術を下支えする。各プログラミングチームの指揮はCTO/CTO補佐が行うが、チーム間の管理業務は管理事務局長とそのスタッフが、ドキュメント等の統一的な管理を、編集局長及び編集局員が行う編成とした。

場合によっては、管理事務局と編集局の局員を減らし、プログラミングチームの数を増やした方が良いかもしれない。営業と連携が頻繁な組織内では、技術営業担当をプログラミングチームに入れる必要があるかもしれない。

「コンセプトの完全性」と、その重要性

steve-jobs

ブルックスは一貫し「コンセプトの完全性」が重要だと指摘している。全体を構成する各要素が、コンセプトを忠実に再現するからだ。

「コンセプトの完全性」は、全体の統一性・調和性として具現化される。

コンセプトの完全性が成立するには、設計(デザイン)は1人または互いに意見が同じで共鳴しているごく少数の頭脳が考え出す必要がある。小規模開発では「執刀医(チーフプログラマー)」がそれを行うが、大規模開発の場合スケジュール制約があるので執刀医が設計(デザイン)を行わない方が良い場合があるかもしれない。その場合、アーキテクチャとインプリ(実装)を分離する方法が推奨されている。そしてこう述べている。

アーキテクトだけがアーキテクチャについて良いアイデアを持っているなどという気は毛頭ない。新鮮なコンセプトは、しばしば実装者や利用者から出てくる。けれども、システムにおけるコンセプトの完全性こそが使いやすさを決定するものである。システムの基本的コンセプトと一致しないなら、優れた機能であれアイデアであれ、除外しておくのが一番だ。そうした重要ではあるものの、取り込めないアイデアがたくさんあるようなら、いったんシステム全部をご破算にして、別緒基本的コンセプトのもとに統一されたシステムをはじめから作り直せばよい。

20周年記念の補足では、MacのGUIとショートカットの例を出し、2つのコンセプトを同居させる事で、初心者(ライトユーザー)と、上級者(ヘビーユーザー)の双方を満足させる道もあると補足している。

3つの重要なコミュニケーション

コンセプトを決定し、その完全性を広く共有するには、コミュニケーションと組織が重要だと説く。そしてコミュニケーションの中で、下記3種類が特に重要だと言う。


1. メールや電話(チャット)による、非公式な方法による問合せ
2. 定期的なミーティング
3. 正式なドキュメント群(手引き書)

正式なドキュメント群(手引き書)

手引き書とは、プロジェクトが生産する「何か」について構造的に管理されたドキュメント群だ。開発者として利用するユーザ(プログラマ)と、ただただ利用するユーザ(業務ユーザ等)では、興味関心が異なるため、利用レベルに応じた異なるレベルのドキュメントが必要だと言う。

手引き書の周知について、当初は「すべてのプログラマーがすべての資料をウォッチするべき」と考えていたブルックスだが、20周年の補足ではそれが誤っていたと述べている。デービッド・バルナスが説いた「モジュールコードは適切に定義されたインターフェースを使って隠匿するべきであり、そのモジュールの内部はプライベートとして外側からは解らないようにするべきだ」という意見に賛成している。私個人としては、バルナスの意見によりつつ、でも興味があればソースを読めばいいんでは。と感じる。

手引き書に含むべき内容として下記が挙げられている。


  1. 目的: 主な機能、このプログラムが必要な理由。
  2. 環境: 実行可能な条件、構成。
  3. 領域と範囲: 有効な入力値と正常な出力値、及びその範囲。
  4. フローチャート、またはサブプログラム構造図: 処理の順番や概要を大まかに理解するのに有用なため、事前に詳細なフローチャートを書く必要性は低い。
    バス構造(処理フロー)、つまりデータあるいはプログラムがテープないしディスクから取り出される順番についての概要と、それぞれのステップで実行される内容
  5. 実現される機能と使用するアルゴリズム: 要するに何をするものなのか。完全な記述、または文献中にあるそうした記述の参照
  6. 入出力フォーマット: 詳細かつ完全に記載する。
  7. オペレーションコマンド: コンソールに出力される、正常及び以上終了処理も記載する。
  8. オプション: 利用時(呼び出し時)に選択できる機能の指定方法。
  9. 実行時間: 指定された環境で指定されたサイズの処理にかかる時間。
  10. 精度および検査: 出力結果に求められる精度、及びその保証方法。テストケースも記載する。
  11. 修正者へのメッセージ: もとのデザインで意図されている修正に関する説明、フックやエグジットの種類と配置場所、およびどんな修正が可能で、どのように修正すべきか制作者の考えを説明。隠された落とし穴についての制作者の考察を含むことも有益

メンテナンスを維持するためにも、詳細フローチャートやその他詳細な記述は、ソースコード中にコメントとして記述することをブルックスは「自己文書プログラム」と呼んで推奨している。そして読みやすさ担保のためは、そのフォーマットを決めておく事が重要だと言う。このあたりはlint等のサポート環境が整ってきている現在に繋がっている考え方だなと思った。

ドキュメントは、散文的(概要的・俯瞰的)な記述からはじまり、徐々に厳密な定義(詳細的・具体的)を記述していく。そして、厳密な定義の保証として、テストケースを含む必要がある。

テストケースは、大きく下記の3分類が紹介されている。

  1. 正常系: 通常入力されるようなデータに関してプログラムの主要機能をテストする中心的なケース。
  2. 境界系: 入力可能最大値・最小値、及びあらゆる種類の有効な例外処理が実行されるか確認し、入力データ領域の境界にあたるところを厳密に検査する、ぎりぎりで規則に合っているケース。
  3. 無効系: 無効な入力で適切な診断メッセージを出すことを確認し、外側から領域境界を厳密に検査する、ぎりぎりで規則からはずれているケース。

銀の弾などない〜ソフトウェアエンジニアリングの本質と偶有的事項〜

silver-bullet

ソフトウェア開発を考える上で、本質的作業と偶有的作業を分けて考える事が重要とブルックスは言う。

本質的作業とは、設計(デザイン・アーキテクト決定)の事で、偶有的事項とは、設計に従って実装しサービスとして提供するための作業だ。

偶有的作業の課題へのソリューションは、プログラム言語の高級化や、マシンの性能向上によって提供されていくが、本質的作業の課題は、将来にわたってもソリューションが産まれづらい。

その理由は、本質的事項の以下のような特性により生じている;


  1. 複雑性: ソフトウェアの細部は、それぞれが似通っていればサブルーチン化されるため、似ている部分が存在しない。ソフトウェアが巨大化すればするほど、非線形に複雑性は増す。そしてそれを複数人で作り、メインテナンスしていくので、誤ったコミュニケーションによる欠陥やコスト超過、スケジュール遅延が産まれやすい。

  2. 同調性: 利用者の考え方(きまぐれ)、社会制度、時代背景に、ソフトウェアは合わせていく必要がある。これはソフトウェアが後からやってきた(誕生してきた)からであり、自然科学とは決定的に異なる性質である。

  3. 可変性: 「機能」を具現化したものなので、求められる機能が変われば、ソフトウェアも変化しなければならない。また物理的存在ではない為、例えばマシン環境が古くなったりリプレイスする場合にも、ソフトウェアは変化の必要に迫られる。

  4. 不可視性:ソフトウェア実体は、ビルの間取り図と異なり、本質的に空間に埋め込めない。ソフトウェアの構造を定義したり単純化したりすることが困難なため、概念上のツールを作る意欲が阻害されている。


この困難にも関わらずブルックスは、大昔の医学が「悪霊信仰や体液説」を「細菌説」に置き換える事に成功したように、ソフトウェアエンジニアリングも、継続的に注意深く課題を解決する事を目指そうと語りかける。

ソフトウェア開発は、スケジュールの遅延や増大する予算、欠陥品質など、悪夢の中の怪物ともいえる恐ろしさと隣り合わせだ。その怪物を一発で倒せる「銀の弾」は、これから10年間(1986年→1996年)にわたって見つかることは無い。それでも、継続的に注意深く課題を解決する事を目指そうというのがブルックスの訴えかけだ。その為に重要な事として下記4点を挙げている。


1. 購入できる物をあえて構築しない
2. 要件定義の際、ラピッドプロトタイピングを使用する
3. 実行・使用・テストを重ねながら、機能追加を通してソフトを有機的(系統的)に成長させる
4. 若い世代のコンセプトデザイナーを発掘、育成する

これはまさに、ソフトウェア工学(エンジニアリング)を、精密で包括的な数学的基礎を持ったエンジニアリング分野と成長させるために必要な考え方ではないだろうか。


書籍DATA

  • 書名: 『人月の神話 20周年記念増訂版 【新装版】
  • 著者: Jr FrederickP.Brooks
  • 訳者: 滝沢 徹, 牧野 祐子, 富澤 昇
  • 発売日: 2014/4/22
  • ページ: 321ページ
  • 出版社: 丸善出版
  • 備考: 株式会社ピアソン桐原より2002/11に出版された同名書籍の横組再出版

目次

第1章 タールの沼
第2章 人月の神話
第3章 外科手術チーム
第4章 貴族政治、民主政治、そしてシステムデザイン
第5章 セカンドシステム症候群
第6章 命令を伝える
第7章 バベルの塔は、なぜ失敗に終わったか
第8章 予告を宣言する
第9章 五ポンド袋に詰め込んだ十ポンド
第10章 文書の前提
第11章 一つは捨て石にするつもりで
第12章 切れ味のいい道具
第13章 全体と部分
第14章 破局を生み出すこと
第15章 もう一つの顔
第16章 銀の弾などない—本質と偶有
第17章 「銀の弾などない」再発射
第18章 「人月の神話」の命題—真か偽か
第19章 「人月の神話」から二十年を経て
エピローグ 五十年間の不思議、興奮、それに喜び

オリジナルの「人月の神話」が1章〜15章に。同じくオリジナルの「銀の弾などない」が16章に。17章は「銀の弾などない」の9年後の振り返り。18章・19章は「人月の神話」の20年後の振り返りを収録する。