「アジャイル」と「ウォーターフォール」

アジャイルがダメだと思う7つの理由へのだいぶ遅い反応

導入

もうだいぶ前の話になってしまいましたが、アジャイルに関するブログエントリ「アジャイルがダメだと思う7つの理由」は予想以上に波紋を呼び、それに呼応していくつものエントリが公開されました。発端となったエントリに関していうと、通常であれば必要となる数々の留保事項や前提事項を書かずに切り込んでいるという点において、間違いなく「煽り」であると言えます。ただ、「アジャイル」という言葉をとりまく数々の事象をかなり的確に指摘することによって、「アジャイル」という言葉をパブリックな場所で語っている少なからぬ人たちに対して、(意識的か無意識的かは問わず)ある種のポジショニングを強いたという意味で、実にいい釣り針なのではないでしょうか。


個別の論点に関する「アジャイルでは全体スケジュールにコミットできない」「いや、アジャイルだって全体スケジュールにコミットできる」という議論は一通り終わった感がありますので、だいぶ出遅れた立場としては、少し違う視点から整理したいと思います。

ところで、「アジャイル」と「ウォーターフォール」は何が違うんでしょうね

反射的に出されるであろう主張とそれに対する反論をいくつか挙げてみます。「ウォーターフォールは出来上がるまでの時間が長い」―本当ですか?ウォーターフォールは一年かけなければならないなどという定義はどこにもありません。「ウォーターフォールではフィードバックを受けられない」―どうでしょう?重要な機能なら必要に応じてプロトタイピングをするなどということは常識です。「ウォーターフォールでは変化に適応できない」―そうでしょうか?顧客がソフトウェアを触るようになって上がってきた諸々の仕様変更を、テストの進捗を考慮しつつ、別の線を引きながら取り込んでリリースに間に合わせる、みたいなことは普通だと思います。また、アーキテクチャ策定段階で、比較的安定している機能と後々変化が予想される機能とで設計/実装方針を区別し、変化に対応しやすい(その代償としてコストのかかる)設計にしておくといったことも当然やるべきことです。


また、ウォーターフォールの基本的な性格とされる「要件定義」→「設計」→「実装」→「テスト」という工程は、フィードバックサイクルの長短に関わらず必要なことであり、これを以てアジャイルウォーターフォールの違いを語ることは難しいでしょう。「基本設計書がすべて出そろってレビューが完了するまでは実装に着手してはならない」といった教条も時折は耳にしますが、それがウォーターフォールのあるべき姿かどうかという疑問と共に、現実としてそこまで厳格な運用が行われているケースはごく稀ではないかと思います。実際には、サブシステム(あるいは大機能など、呼び方は色々あると思いますが)といった、一定の粒度でシステムを分割し、各工程を並行させると共に、実装も着手できるところから着手しているでしょう(そのリスクを発注側と受注側のどちらが持つかは別として)。


つまり、現実の開発においては、「変化の方向性を先読みしつつ、フィードバックを適切に受け取ること」が重要なのは間違いなく、そのための施策は色々とあるわけです。ただ、そういった諸々の施策を「アジャイル」と呼び、そうではないものを「ウォーターフォール」と呼んで思考停止するのは、色々と不幸なことを引き起こすと思うのです。一方で、アジャイルの主張する「変化への適応」に気を取られすぎて、「事前に考えること」を否定することも逆方向の思考停止です。「それは後で考えれば良い」という台詞は、後で発生するであろう揺らぎを吸収できるスケジュールとアーキテクチャに支えられてはじめて説得力を持ちます。事前に計画を立てること、全体像を描くこと、全体の中で個別に戦略を考えること...総じて先のことを予め考え、読んでおくことは常に必要です。そういった「考えること」の放棄に「アジャイル」という名前を冠することに対しては、同様に強い危機感を覚えます。


結局のところ、「考えてわかることは、考える。考えてもわからないことは、どうすればわかるかを考えたうえで、そこまで手を進めてみる」という基本がすべてで、それ以上でもそれ以下でもないということです。


とはいうものの、世の中に目を向けてみると、ここまで「アジャイル」という言葉が盛り上がる背景には、"これまでの"開発がうまくいっていないという感覚あるいはある種の閉塞感が存在するのだろうとは思います。つまり、批判されるべき「何か」は現実に存在し、それへの批判として別の「何か」が存在するのは事実で、それぞれがウォーターフォールアジャイルという名前をまとっているだけではないか、と感じるのです。それが一体何であるのか、普段受託開発を行っている自分の経験をふりかえりながら言葉にしていきたいと思います。

チームと文化

批判されるべき「何か」は、プロセスや成果物ではなかろう、ということが出発点です。プロセスにしても成果物にしても、コンテキストに応じて適切なものを選んでいけばよいものだからです。むしろ「コンテキストに応じて適切なものを選ぶ」ことができない環境にこそ問題視すべきだと考えます。

単能工とコマンドコントロール

基本設計書を書くだけの"SE"。設計書の内容を実装するだけの"PG"。よく話題にあがりますね。「それではダメだ」という批判と、「実際にそういう人たちが集まってシステム開発をしているんだ」という現実路線の両方が存在すると思います。僕自身の経験に照らせば、一定以上の規模であれば、実装がある程度わかる人が設計書を書き、設計の矛盾に気づける人が実装し、双方のコミュニケーションが円滑に進んでいる状態が現実的で健全な開発であるという気がします。それでも工程ごとに担当者が分かれれば、そのコミュニケーションを繋ぐための中間成果物が必要になるのであり、そういう中間成果物が「お客さんと要件を詰め、過不足のないドキュメントを描き、柔軟かつ統一のとれたアーキテクチャでそれを実装して、鉄壁のテストをやってくれるエンジニア」から見て無駄なオーバーヘッドに見えてしまうのは仕方が無いことだと思います。そういうエンジニア2,3人で開発できる規模なら、また違ったやり方もできるでしょう。


工程ごとに担当者が分かれていても、工程間がスキル的にもコミュニケーションパス的にもゆるやかにつながってフィードバックが回っていれば、それほど問題にはならないと僕は考えています。問題なのは「あらゆる指示が上から降ってきて、ただ決められた期日までにその指示をこなす」ことが求められる環境です。これを生み出すのは、同一工程内の階層化、具体的に言えば、少数の「タスクを分解し指示する人」と多数の「指示に従ってタスクを遂行する人」との分断です。工程ごとに作業者が分かれていて、かつその作業が上から降ってくるという構造であれば、メンタリティとして成果物の提出先が「仕事を割り当てる人」になってしまい、それを受け取る次工程の人が忘れ去られてしまうのもわからなくはないですが、当然いい結果は生まないでしょう。


個人的には、この「分解されたタスクの指示書」がWBSの姿をしていることこそが、この構造が「ウォーターフォール」と呼ばれてしまう原因ではないかと思っています。ただ、もはや開発モデルとしてのウォーターフォールは関係ないですよね。ここにあるのは、「多重階層によるコマンドコントロール」と「成果物を壁の向こうに投げつけるサイロ構造」です。フィードバックが届かない多重階層構造によって人が病み、サイロ構造によって成果物の品質も下がるのはよくわかります。

多能工と自己組織化

「お客さんと要件を詰め、過不足のないドキュメントを描き、柔軟かつ統一のとれたアーキテクチャでそれを実装して、鉄壁のテストをやってくれるエンジニア」に話を戻します。そんなスーパーマンがいたとして、その人も始めからそうだったわけではないでしょう。要件定義、設計、アーキテクチャ策定、実装、テストといった各工程を個別に経験する中で知識と技術を蓄積した結果にすぎません。つまり、多能工になるためには、工程を横断して様々な経験をする必要があるわけですが、前述の文化ではその経験を積むことができません。


「多重階層によるコマンドコントロール」では多能工が育たず、多能工が育たないから「多重階層によるコマンドコントロール」が必要になるのです。この負の連鎖を断ち切るために、単能工とコマンドコントロール、多重階層の関係をもう少し整理しておきます。作業をする人が見ることのできる範囲が狭い場合、その狭い範囲に応じたチャンクにまで仕事を細分する必要があります。そして、その負荷は、指示をする人に集中することになります。一人で見ることのできるノードの数には限りがありますので、作業者が食べられるサイズになるまでに階層ができあがるのはよくわかります。


つまり、「指示を出す人/従う人」という構造に無理があるのです。では、違う道はどこにあるのでしょうか。「正解」ということではないのですが、受託開発のリーダーという立場で自分のやっていることは、「指示出し」ではありませんので、少しふりかえってみたいと思います。


...さて、僕は何をやってるんでしょうね。感覚を言葉にすると、対チームとしては「大きな方向づけと情報の流れのコントロール」、対顧客としては「窓口」ですかね。考えてみると、作業の細分化はほとんどメンバーに任せてます。得意分野を中心に緩やかに周辺をカバーできるメンバーに囲まれているので、渡せる仕事のチャンクが大きく、作業分割と統合にコストがかからないんですね。コストがかからない、というよりそこに自分が入ると、自分がボトルネックになって効率が落ちてしまう、という表現が正しいです。また、大きな方向づけと書きましたが、進め方も自分だけで決めているわけではなく、あまり時間を気にせずに、よく議論している気がします。とはいえ、和智「どうしたらいいと思います?」○○「こうですかね?」和智「じゃあそれで」○○「」というパターンが頻出している気もして、エントリを書いていて、改めてメンバーに恵まれていると思いました。要は自分がボトルネックにならなければ順調に開発が進むわけで、ボトルネックにならないコツは、情報の流れをプッシュ型からプル型に変換することだと思っています。「大きく渡して、必要に応じて聞いてもらう」というやり方ですね。

終わりに

ソフトウェア開発を生業としていれば、さまざまな業務に関わることになります。やることが大きく、作るべきものが最初から分かっている業務であれば、コストを抑える代償に変化を想定しないアーキテクチャで進めることができるでしょうし、そもそも何をするかもわからないうちから実験的にモノづくりを始める状況であれば、変化に柔軟に対応できるアーキテクチャをインクリメンタルに膨らませていくべきでしょう。


重要なのは常に、「何のために何を作るのか」という目的であって「どう作るか」は手段でしかあり得ません。それに対してエンジニアとしてできるのは、専門性を高めることと守備範囲を広げることを通じて、どういう要求にも対応できるようになっていくことかありません。顧客が満足するものを提供しつつ、プロジェクトを通じてメンバーが成長できるのであれば、開発手法は別に何でもいいと思うのです。