余談ですが、ウォーターフォール開発において、なくてもほぼ困ることがない64%の機能がなぜ実装されてしまう(別の言い方をすれば、無駄なコストをかけている)のでしょうか?その理由はリリースの頻度にあります。ウォーターフォールでは、リリースは基本的に一度だけです。そのため、要求を提示する発注者側は、要求定義の段階で全ての要求を提示してしまわない限り永遠に実現されないという強迫観念にも似た感覚にとらわれ、たとえ使う可能性がどんなに低くても、要求に不確定要素があったとしても、とにかくその要求をねじ込むという行動に出ざるを得なくなります。
筆者自身も、「使うかどうかは分からないが、この要求を今入れておかないと入れるチャンスは永遠に失われるので、申し訳ないが何が何でも入れてほしい」というリクエストに遭遇したことは1度や2度ではありません。そしてリリース後1~2年が経過したタイミングで、それらの機能が実際に使われたかどうかを保守チームに確認すると、「1回も使っていない」というお決まりの回答が返ってきます。有名な「YAGNIの法則」(YAGNIは「You ain’t gonna need it」の略。「どうせ必要ないのだから、必要性がはっきりするまで何もしないのがよい」を意味する)はそこから生まれたわけですが、アジャイルでリリース頻度が増え、要求をバックログに定常的に追加する機会が生まれれば、前述のような非効率は自ずと解消されることでしょう。
順調だったものがなぜ突然順調でなくなるのか
ここまで、アジャイルとウォーターフォールでの品質(Q)、コスト(C)、納期(D)の制御の仕方の根本的な違いについて解説してきましたが、もう1つ、実際に起きた例を用いてアジャイルの見積もりと計画作りの優れている点を解説します。
あるプロジェクトにおいて、筆者が参画する1つのアジャイル開発チームと、2つのウォーターフォール開発チーム、計3チームで開発を担当していました。実際のリリースに当たっては各チームの成果物を統合し、品質を検証する必要があります。定期的にチーム合同の進ちょく会議を実施していましたが、リリース3週間前の時点でウォーターフォールの1チームは「順調です。進ちょく度を正確に数字で示すのは難しいですが、感覚的には70%ぐらい完了しています」と報告していました。
ところが、リリースが1週間後となったある日、突如そのチームから「完了させられる見通しが立たないのでリリースを2週間ずらしてほしい」との申し出がありました。また、アジャイルチームが使用するデータの準備を担当していたもう1チームからは、データの準備が当初期日に間に合わなかった際、「一日遅れても大きな問題になるとは思っていなかった」との釈明を受けました。
不幸にも上記のような事象が発生した理由はいろいろ考えられますが、アジャイルとの比較でいえば、動くもので検証する頻度や、日々の状況の確認の強度といった基本的な行動原理の違いが品質面での差として現れていたように思います。
アジャイルチームは数週間に1度、実際にエンドユーザー向けにリリースするかどうかは別として、リリースしようと思えばできるレベルのものをくみ上げています。自分たちが数週間というスプリントの期間でだいたいどの程度のものを作ることができるのか、肌感覚で分かっており、「いつ頃、どの程度のものをリリースできそうか」ということを、ウォーターフォールと比較して高い精度で見通すことができるようになっています。また、数時間単位に作業を分解し、課題があれば日次ミーティングで共有し、早期にそれらを解消することに集中します。そのため、基本的に進ちょくを週次でしか見ないウォーターフォールと比較して早い段階で問題の所在に気づき、対処することができるのです。これら2点について、以下でより詳細に見ていきましょう。
動くもので何度も検証する
アジャイル開発では、実践していく中でおのずと品質が高まる仕組みが備わっていきます。アジャイル開発では常に「動く状態」にしておくことを重要視しており、生成されたプロダクトを動く状態でステークホルダーによるレビューを実施することが求められます。このことについては、アジャイルソフトウェア開発宣言にある価値基準の1つで「包括的なドキュメントよりも動くソフトウェアを」の一文からも読み取れます。また、動く状態とは、求められる実現範囲において、本番に沿った環境で、必要な機能が正常に網羅的に動作している状態であることが求められます。すなわち、実際のユーザーへすぐにでも提供可能な状態にしておくことになります。
加えて、動く状態にしておくことは、ステークホルダーへレビューを実施する時だけに限りません。動く状態にしておくことは、日々の作業でも同様です。アジャイル開発の通例としては、「夜間ビルド」といった1日の開発作業の終わりに、他の開発メンバーが担当したプログラムとの結合も含めた検証を実施して、その時点までに開発された部分だけで動く状態にします。これによって、不具合は日々検知され改善されるので「技術的負債」と呼ばれるような不良個所の蓄積は軽減され、品質の精度は高まります。
また、後続の開発サイクルで新しい機能が追加となった場合でも、サイクルの中で新しい機能と前回分までに実現した機能との整合性を確認する検証作業を行い、プロダクト全体としても常に正常に動作している状態を保つようにします。開発サイクルは数週間の間隔で何度も実施されるため、必然的に検証も何度も行われることになり、確実に品質も向上していきます。