ソフトウェアの世界では、ソフトウェアプロセスの方式を説明するときに「ウォーターフォール」という言葉がよく使われる。これは、反復型あるいはアジャイル方式の考えとは対照的なものだ。ソフトウェアの世界でよく知られている用語の多くがそうであるように、この「ウォーターフォール」も意味が明確に定義されておらず、起源もあいまいである。だが、その本質的なテーマは「大きな労力を活動をベースにしたフェーズに分割する」ことだと私は考えている。

「ウォーターフォール」という言葉がどのように広まったかは定かではない。だが、その起源はWinston Royceの論文とされており、以下の図を参照することが多い。

この論文は(滝のようにタスクが流れ落ちていく形状から)ウォーターフォールの考えの起源であると広く認知されている。だが、「ウォーターフォール」という言葉は、この論文には登場しない。この名前が後にどのように登場したかは定かではない。

Royceの論文は、当時(60年代後半)のソフトウェア開発プロセスの観察結果と、通常の実装ステップをどのようにすれば改善できるかを示しているにすぎない1。だが、「ウォーターフォール」はさらに先まで行ってしまい、ソフトウェアの開発方式の一般的な説明として使われるようになった。私も含め、ソフトウェアのカンファレンスで講演する人たちは、必ずと言っていいほどウォーターフォールを軽蔑の対象として登場させている(ウォーターフォールの利点を話している講演を何年も耳にしたことがない)。だが、企業の実務家を相手にした講演では、ウォーターフォールは価値のある(むしろそのほうが好ましい)開発方式とされている話を耳にする。90年代に比べると少なくなってきてはいるが、プロセスの専門家の話を聞く限り、その頻度はみんなが思っているよりもずっと多い。

「ウォーターフォール」とは一体何だろうか?これは簡単に答えることができない質問である。ソフトウェアの多くのことがそうであるように、ウォーターフォールにも明確な定義がないからだ。だが、私の考えでは、さまざまなウォーターフォールの定義に共通した、ひとつの特徴が存在する。それは「労力を活動をベースにしたフェーズに分割する」という考えだ。

これらのフェーズを紐解いてみよう。たとえば、私があるソフトウェアを構築するとしよう。それには1年かかる。「それじゃあ、1年後に完成したら言ってくださいね」などと言ってくる幸せな人はいないだろう。通常であれば、1年を小さな塊に分割しようとするだろう。そして、進捗を監視して、軌道に乗っていることに確信を得たいと思うはずだ。ここで質問。どうやって分割するのだろうか?

Royceの図が示すウォーターフォール方式では、実施する活動によって分割する。1年間のプロジェクトであれば、分析に2か月、設計に4か月、コーディングに3か月、テストに3か月、のようになる。一方の反復方式では、高レベルの要求(図書館マネジメントシステムの構築)をサブセット(蔵書検索、書籍予約、貸出、返却、罰金)に分割する。その後、いずれかのサブセットを選択し、数か月かけて動作するソフトウェアを構築し、該当する機能を実装して、ステージング環境や(できることなら)本番環境にデリバリーすることになる。ひとつのサブセットが終わったら、次のサブセットを続けていく。

ウォーターフォールの考えは「すべてのフィーチャについて、一度にひとつの活動を実施する」であり、反復型の考えは「一度にひとつのフィーチャについて、すべての活動を実施する」である。

「ウォーターフォール」の言葉の起源がはっきりしないというのなら、このフェーズベースの分割の起源はどこにあるのだろう?これは私の推測になるが、大きなタスクをさまざまな活動に分割するというのは、特に建築の活動を参考にしていたならば、ごく自然なことなのだろう。各活動にはさまざまなスキルが要求される。したがって、コーダーを集める前に、アナリストに分析を終わらせようとするのは、直感的に理にかなっている。コーディングを開始する前に要求の誤解を解決したほうがコストが安い、というのは論理的に思える。60年代後半のコンピューターの状態を考えればなおさらだ。最終的に、活動ベースの分割は多くのプロジェクトの標準として使われるようになった。その一方で、フィーチャベースの分割はなかなか教えられなくなっていった2

ウォーターフォールの考え方がソフトウェア開発に適していない理由を説明できる人を見つけるのはそう難しくないだろうが、ここでは私のウォーターフォール方式に対する主な異論をまとめておきたい。ウォーターフォール方式では、サイクルの最終フェーズにテストと統合が用意されていることが多いが、これらは開発プロジェクトにおいて最も予測が難しい要素である。これらのステージで問題が見つかると、それ以前のフェーズの多くのステップで手戻りが発生し、プロジェクトの大幅な遅延につながる。遅延したフェーズを「完了」したと宣言するのは簡単だが、やり残しの作業が多ければ、プロジェクトが順調かどうかを判断するのが難しくなる。また、すべてのフィーチャが完成するまで、早期にリリースできる余地もない。こうしたことすべてが、開発活動に大量のリスクをもたらすことになる。

さらにウォーターフォール方式は、予測型の計画づくりを強制してくる。このことは、あるフェーズ(たとえば要求分析フェーズ)が終わると、その成果物は後続のフェーズが乗っかる安定したプラットフォームになることが前提となっている3。実際には、ソフトウェアプロジェクトの大半は、数か月以内に要求を大きく変えることになる。その原因は、みんながドメインについて学ぶことだったり、ソフトウェアの環境の特性だったり、ビジネスの環境の変化だったりする。実際、フィーチャのサブセットをデリバリーすることで得られるのは、次に何をすべきかが明確になることに他ならない。つまり、反復型のアプローチによって、適応型の計画づくりに移行できるようになるということだ。本物のソフトウェアが必要とすることを学びながら、計画をアップデートしていけるのである4

以上が、これまで私が「成功させたいプロジェクトならば反復型開発を使用すべき」と何度も主張してきた主な理由である。

ウォーターフォールと反復型が内部で組み合わさっていることもある。たとえば、6年間のプロジェクトがあるとする。これは、ウォーターフォール方式の3年間のプロジェクト2つで構成されているが、後半のプロジェクトではフィーチャが追加される可能性がある。トップレベルから見ると、これはウォーターフォールのイテレーションが2つあると考えることもできる。だが、イテレーションが大規模で数が少ないため、私はこれをウォーターフォールのプロジェクトと見なすだろう。反対に、16回のイテレーションで構成されているプロジェクトがあるとする。イテレーションの期間は1か月だが、いずれもウォーターフォール方式で計画されている。私はこれを反復型のプロジェクトと見なすだろう。理論的にはいずれかに分類できない中間的なプロジェクトが存在する可能性があるが、実際にはいずれかのスタイルが優位に働いており、簡単に見分けることができる。

前半のフェーズ(要求分析、概要設計)はウォーターフォール方式で、後半のフェーズ(詳細設計、コーディング、テスト)は反復型と、両者を組み合わせることも可能ではある。これにより、テストと統合のフェーズに固有のリスクは軽減されるが、適応型の計画づくりが可能になるわけではない。

ウォーターフォールは、アジャイルソフトウェア開発の対抗馬としての役割を担わされることが多い。だが、私はこれは厳密には正しくないと考えている。確かにアジャイルプロセスには反復型のアプローチが必要であり、ウォーターフォール方式で作業することなどできない。だが、反復型のアプローチ(非ウォーターフォール)に従っているが、アジャイルではないことも可能である5。たとえば、100のフィーチャがあったときに、10のイテレーションに分割することもできる。各イテレーションでは、計画したフィーチャを納期通りに完成させることが求められる。このとき、私の初期の計画は予測型の計画になる。すべてがうまくいくのなら、物事を計画通りに進められるだろう。だが、アジャイルの考え方には、適応型の計画づくりが必要不可欠な要素である。フィーチャはイテレーション間で移動し、新しいフィーチャが登場することもあれば、価値がなくなったフィーチャが破棄されることもある。

・ウォーターフォールプロジェクトでは、初期のフェーズを安定させる必要があるため、予測型の計画づくりが必要になる。

・反復型のプロジェクトでも、予測型の計画づくりを使うことがある。初期の計画づくりで、イテレーションで実施するフィーチャを固めるのである。

・だが、反復型のプロジェクトでは、適応型の計画づくりを使うこともできる。作業を続けながら継続的に、フィーチャをイテレーション間で移動させたり、新しいフィーチャを発見したりする。

・適応型の計画づくりは、アジャイルプロセスでは必要不可欠である。

私の経験則を述べよう。「納期通りかつ予算通りなので成功」と言っている人は、たとえ反復型プロセスに従っているとしても、それは予測型の計画づくりの観点で考えているのである。そして、それはアジャイルマインドセットの考え方ではない。アジャイルの世界では、数か月前の計画書に何が書いてあろうとも、成功はビジネス価値で判断する。計画は作る。だが、定期的にアップデートする。計画は次に何をすべきかを決めるガイドとなる。だが、成功基準として使うものではない。

謝辞

社内メーリングリストに投稿したドラフトに意見をくれた方々(Ben Noble, Clare Sudbury, David Johnston, Karl Brown, Kyle Hodgson, Pramod Sadalage, Prasanna Pendse, Rebecca Parsons, Sriram Narayan, Sriram Narayanan, Tiago Griffo, Unmesh Joshi, Vidhyalakshmi Narayanaswamy)に感謝する。

注釈

  1. かなり多くの人たちがRoyceの論文を解読しようとしてきた。ここで私が引用した図2が示すプロセスには欠陥があることを説明しているのだから、この論文はウォーターフォールに反対するものだと主張する人もいる。確かに彼は欠陥について触れている。だが、このアプローチは「基本的には健全(fundamentally sound)」とも述べている。確かにこのプロジェクトを活動ベースで分割するやり方は、その後の数十年にわたって受け入れられるモデルとなった。 

  2. これが「ウォーターフォール」という言葉のもうひとつの共通の特徴につながる。それは、全員に何をすべきかを伝える厳格なプロセスであるというものだ。90年代のソフトウェアプロセスの人たちは指示的な手法を追い求めていた。こうした指示的な思考は、反復型のテクニックを提唱している人たちにも影響を与えたのである。アジャイル手法はこのようなテイラー的な考え方を明確に否定しているが、このルートをたどってしまった偽アジャイルの話をよく耳にする。 

  3. 次のフェーズが開始するまでに前のフェースを終了する考えは、便利な作り話である。ウォーターフォールの非常に熱心な提唱者でさえ、実際には以前のステージで手戻りが発生することを認めている。ただし、完璧に実行していれば、手戻りは発生しないとも主張している。Royceの論文では、隣接したステップ(たとえば図にあるAnalysisとProgram Design)で反復が発生する可能性を明確に説明している。だが、手戻りの期間が長いと(たとえばProgram DesignとTesting)、深刻な問題になるとも述べている。 

  4. 反復型よりもウォーターフォール方式のほうが適した状況があるのか、という疑問を抱くかもしれない。理論的には、要求と使用する技術について深く理解しており、その両方がプロダクトの期間中に大きく変わることのない状況であれば、ウォーターフォールのほうがうまくいく。ここで「理論的には」と言ったのは、私はそのような状況に遭遇したことがないからだ。したがって、現実的にウォーターフォールが適しているかどうかは判断できない。後半のフェーズ(コード・テスト・統合)でウォーターフォール方式に従わざるを得ないような状況でも、私はコーディングとテストを繰り返し、継続的に統合するほうがいいと思うはずだ。 

  5. 90年代のオブジェクト指向の世界でも、ウォーターフォールは悪い考えであり、反復型に置き換えるべきだと広く受け入れられていた。だが、アジャイルコミュニティで見られる、要求の変化を受け入れる様子は見られなかった。