アジャイルな開発でデスマーチは回避できるのか
この業界には「デスマーチ」という言葉がある。現実的ではない開発スケジュールを設定してエンジニアに過酷な労働を強い、その結果生産されるコードの品質が落ち、次々に発生するバグのためにますます過酷な状態に陥るプロジェクトのことを指す。
デスマーチの根本の原因は、プロジェクトマネジメントにある。現実的ではないスケジューリング、エンジニアの生産効率への過信、過酷な労働環境、非効率な開発環境、ラストスパート型の開発スタイル、などである。
特に日本のIT企業における「元請けが受注、実際の開発は下請け」というゼネコンウォーターフォール型のプロジェクトにおいて、実際にコードを書かないアーキテクトが机上で設計をするという悪習慣がある。これが、設計時(もしくは計画時)の見積りと実際の開発期間に大きなズレを生じさせ、下請け企業に過酷な労働環境を強いる原因の一つにもなっている。
しかし、「だからアジャイルな開発スタイルのほうが良い」と結論付けるのは短絡的である。アジャイルな開発スタイルであっても工数の見積りは必要で、その見積りが実際と異なるケースは頻繁にある。
アジャイルな開発スタイルが優れているのは、「少しずつ作ってはこまめにリリースしていく」部分にあり、それゆえプロジェクトのリスクが早めに可視化される点にある。そのため、「機能を削って納期に間に合わせる」「プロジェクトの遅れを早めに感知してスケジュールの見直しをする」「当初設定したアーキテクチャの欠点を途中で修正する」などの柔軟な対応が比較的容易なのである。
つまり、「アジャイルな開発スタイルであればデスマーチには陥らない」というのは大きな誤解であり、実際には「アジャイルな開発スタイルであれば、デスマーチへの突入を早めに感知して対策を取ることが可能」なだけである。
デスマーチの責任は誰にあるのか
ではどうやったらデスマーチを回避できるのだろう。大切なのは、プロジェクト当初の工数見積りと基本設計の段階であり、ここで基本設計を担当するアーキテクトの役割が最も重要だと私は考えている。
アーキテクトは自らプログラムを書く経験を十分に積んだエンジニアで、「実際にコードを書かずに基本設計をすることはとても難しい」ことを肌で知っている人でなければならない。そんなアーキテクトが、ソフトウェア作りの難しさをちゃんと理解したうえで、基本設計と工数見積りに取りかかることが何よりも大切なのである。
私はこの業界で、「使えない」アーキテクトに何人も出会ってきたが、彼らに共通して不足しているのは、「自ら苦労してプログラムを書いた経験」である。特に日本の「大手ITゼネコン」と呼ばれる企業に多いのだが、せっかく理系の大学を出ておきながら、ほとんど「現場のプログラマ」としての経験も積まずに、プロジェクト管理やアーキテクトの立場におかれてしまい、「机上のアーキテクト」と化している人たちである。
実際に自らがプログラマとして苦労した経験があれば、プログラムを書いてみなければわからないことがたくさんあり、良いソフトウェアを作るためにはプログラムを書きながらアーキテクチャを柔軟に変更していかねばならない、などの良いソフトウェアを作るための肝となる部分がわかってくる。
しかし、日本のIT業界のように、自らプログラムを書いた経験があまりない上流の「机上アーキテクト」が上位設計のみして、実際のプログラミングを下請けに丸投げするという開発スタイルでは、この「プログラムを書きながら、そこでの発見を反映してアーキテクチャを修正していく」というフィードバックサイクルがうまく働かない。
その結果、プロトタイプも作らずに制作した「机上の考察のみで作ったアーキテクチャ」が仕様書として下流のプログラマに渡り、下流のプログラマたちは文句も言わずに(もしくは言えずに)その仕様書通りにひたすらコーディングをする、という開発スタイルがまかり通っているのだ。元請け→下請けという上下関係があるゆえに、「実際にプログラムを作ってみて見えてきたアーキテクチャの問題点」などが反映されることもなく、プロジェクトはデスマーチに陥っていくのである。
アーキテクトの役割
ここで重要なのは、アーキテクトの役割は、単に基本設計をするだけではなく、設計を通じてプロジェクトを成功に導くことにあることを認識することである。
基本設計に問題があればどんなにプログラマが頑張ったところで良い物はできないのは当然だが、それよりも重要なことがある。それは、アーキテクト自身が、「プログラムを書いて実際に動かしてみるまでは、設計が適切なものかどうかはわからない」ことをちゃんと理解したうえで、リスクを最小限にするには何をしたらよいのかをあらかじめ考えてプロジェクトに取り組むことである。
最も効果的なのは、見積りの段階でのプロトタイプの作成である。
私が「見積りの段階でプロトタイプを作るべきだ」と主張すると、「プロジェクトが正式にスタートしていない段階でプログラマをアサインする余裕はない」と反論するアーキテクトがいるが、この反論は二重の意味で間違っている。
まず第一に、プロトタイプの段階でプログラマをアサインしようとしている点が大間違いである。見積りや基本設計のためにプロトタイプを作るのはアーキテクト自身の役割である。自ら手を動かしてコードを書けないアーキテクトに、良い設計など絶対にできない。一般のプログラマよりも数倍の生産効率でコードを書けるエンジニアでなければ、良いアーキテクチャなど作れないのだ。
第二に、プロトタイプの手間を嫌がっていては良い設計などできない。そもそも、優秀なアーキテクトは、普通のアーキテクトが仕様書を書くのと同じかそれより速いスピードでプロトタイプを作れなければならない。そして、そのプロトタイプ作りを通じ、設計の問題点を修正したり、工数の見積りをするのがアーキテクトの役割だ。
リスク軽減のためのプロトタイプ
プロトタイプによるリスクの極小化は、特に「誰も作ったことのない」ソフトウェアを作る際には重要である。先日も、iPhoneのカメラで取り込んだ動画をリアルタイムでHTTP Live Streaming[1]を使って配信する、というプロジェクトの話があった。最初にこの話を聞いたときは「とてもリスクの高い」プロジェクトだと直感した。今まで誰も実現したことがなかったからだ。
調査をした結果、ハードウェアのエンコーダを使うためには、取り込んだ映像をMPEG4のファイルとして一度格納し、それをMPEG2-TSというフォーマットに変換する必要があることがわかった。理論的には可能だが、エンコーディングとフォーマット変換の処理に加えてHTTP経由のリアルタイムストリーミングをすることがiPhoneのハードウェアで可能かどうかは実際に作ってみないとわからない。やはり、かなりリスクの高いプロジェクトだ。
そこで、プロトタイプを通じて実証実験をすることにした。まず最初に作ったのは、前もって複数セグメントに分割したMPEG2-TSファイルをHTTP経由でストリーミングするサーバである。最初に作ったものは、実際に走らせてみるとやたらとメモリを消費することが判明した。そこで、メモリマップドI/O[2]とパイプライン処理[3]を組み合わせたアーキテクチャに変更することにより解決した。この段階で、少なくとも通信の部分に関しては、十分に実現可能なことが判明した。
次に作ったのは、ビデオから取り込んだ画像を、数分ごとのセグメントに分けてMPEG4ファイルとして次々に格納していく部分である。最初はAVCaptureMovieFileOutputというしくみを作って実装してみたが、これだとセグメント間にギャップができてしまうので、代わりにAVAssetWriter を使ってそのギャップをなくす方法に切り替えた。
最後に作ったのが、生成したMPEG4ファイルをMPEG2-TSファイルに変換する部分で、これだけはCPUに負担をかけるので、できるだけオーバーヘッドを減らすように実装し、最終的には2秒のセグメントを0.2~0.3秒で変換できるところまで最適化できた[4]。
ここまでできた段階で、このプロジェクトが現実可能であることはほぼ証明できたが、念のために上の3つを組み合わせ、実際にVGA相当の解像度の映像を4チャンネル同時ストリーミングできることをiPhone 4S上で確認した。
以上の作業に1週間ほど費やしたが、ここまでできたところではじめて、私はアーキテクトとして責任を持って「このプロジェクトは現実可能である」と自信を持って言えたし、最終製品を作るに必要な工数を見積もることが可能になった。プロトタイプなしでは、開発にどのくらいかかるか予想するのはとても難しかったし、そもそも、実現可能かどうかすらわからなかった。
研究開発投資としてのプロトタイプ
この手の話をすると、ほとんどの場合「うちの会社は受託開発中心の会社なので、プロトタイプを作っている余裕などありません。顧客から仕事を受注する前にプログラムを書くことなどできません」という返事が返ってくる。
気持ちはわからないこともないが、そんな経営姿勢では、上のストリーミングアプリの開発のようなリスクの高い仕事は受けられないと私は思う。実証実験もせずに仕事を受注してしまったら、デスマーチに陥る可能性も高いし、製品を納入できなくなってしまうリスクすらあるのだ。
それよりも、少なくとも1週間ぐらいの時間を費やしてアーキテクトが自らコードを書いてプロトタイプを作り、プロジェクト全体のリスクを把握したあとにスケジューリングすべきだと私は思う。
万が一、それが仕事の受注につながらなかったとしても、作ったプロトタイプとその過程で取得したノウハウは会社の財産になる。中途半端な「ソフトウェア研究所」のようなものを作るよりは、はるかに実質的な価値を生み出す研究開発投資になる。