私の開発スタイル
私は30年以上もソフトウェアエンジニアとして飯を食ってきており、開発スタイルに関してはかなり強い意見を持っているほうだ。私の開発スタイルを見た人は誰もが「中島さんのスタイルは究極のアジャイルですね」と言うが、実は私はあまりこの「アジャイル」という言葉は好きではない。
仕様書を書こうが書くまいが、開発スタイルを何と呼ぼうが、「良いソフトウェアを作る」ためにはいくつか注意しておかなければならないことがある。それを「なぜそれが必要か」という本質的な部分から理解して取りかからなければ、何の役にも立たないのだ。
「アジャイル」という言葉に踊らされて、「なぜ頻繁にリリースしなければならないのか」「なぜ仕様書の作成にあまり時間を費やしてはいけないのか」ということを理解せずに、形だけアジャイルにすることは、「オブジェクト指向」の本質を理解せずにC++でプログラムを書くことに相当する。C++を使っていてもスパゲッティコードを書く人もいれば、Cやアセンブラで美しいオブジェクト指向のコードを書く人もいるのだ。
そこで今回は、私が実際にどんな形でソフトウェアを作るかを、現在開発中の教育アプリ(neu.Tutor)の開発過程を通して紹介し、その中で「ソフトウェア作りに関して何が大切か」を書いていく。
ビジョンの共有
このプロジェクトは、ハーバード大学でも教鞭をとったことがある(株)アクティブラーニングの羽根拓也氏との共同開発プロジェクトである。私がブログに書いた「ぜひとも起こしたい『教科書革命』」というエントリを読んだ羽根さんが私にコンタクトしてきたことがキッカケとなりスタートしたプロジェクトである。
初対面のときから、羽根さんは彼が長年温めていたアイデアを熱く語ってくれた。それは、「勉強のしかたそのものを教える教師」として蓄積してきたノウハウを満載したスマートフォンアプリを作りたい、というものであった。
もともと教育に興味があった私は、「ではさっそくプロトタイプを作ってみましょう」と返事をしてシアトルに戻ったのだが、いざ作ろうとするとなかなか良いアイデアが浮かんでこない。iTunes Storeで配布されている教育アプリをいくつかダウンロードして試してみたが、どれもみな、紙のフラッシュカードをアプリに置き換えただけの単純なものである。同じようなものを作ることは簡単だが、それでは何の意味もない。そう考えているうちに、初期の勢いは一気に失せてしまった。
そのまま1ヵ月ほど放置し、次の日本行きの日程をFacebookに書いたところ、すぐに羽根さんから「もう一度会いたい」とコンタクトしてきた。プロトタイプも作っておらず、少し気まずいとは思ったのだが、プロトタイプの作成を約束したこともあり、しかたがなく会うことにした。
2回目のミーティングでは、羽根さんもかなり具体的なポイントを語りはじめ、その時点でようやく私の中で「何を目指して作ればよいのか」が見えてきた。もちろん、細かな仕様などは決まっていなかったが、「既存の教育アプリとはどこが違い、どんな価値をユーザに提供するのか」という「プロダクトのビジョン」が共有できたのである。
帰国後さっそく、私なりに理解した「ビジョンステートメント」(注1)を書き、羽根さんと同じところを目指していることを確認することに時間を費やした。
私にとっては、この「ビジョンの共有」こそが何よりも大切で、そこさえしっかりと共有できていれば、細かな相談などせずに実装しても方向性を間違えることはないし、商品のコンセプトがぶれることもない。より良いものにするためであれば、一度作ったものを大改造することには労力を惜しまないが、商品のコンセプトが途中で変わってしまったのではたまらない。
そんな無意味な仕様変更を避けるためにも、プロジェクトの開始時に商品のコンセプトをしっかりと定め、開発メンバーの間でビジョンを共有しておくことが大切なのだ。
プロトタイプを作成しアーキテクチャを検証する
ビジョンが定まると、まず最初に私が作ったのはプロトタイプである。長年のソフトウェア開発を通じてたくさんのことを学んだが、その中でも最も大切なことは「まずはプロトタイプから始め、少しずつアーキテクチャを固めていくこと」だと確信している。
どんなに賢いエンジニアでも、実際にコードを書かずに良いアーキテクチャを作ることはできない。もちろん、経験を積んだエンジニアであれば、コードを書かずに大まかなアーキテクチャを頭に描くことはできるが、その段階でのアーキテクチャは、「たたき台」に過ぎない。
初期の段階でプロトタイプを作るのは、その「たたき台」が実用的なものかどうかを確認する作業である。細部を無視し、まずは大まかな流れをざっくりと作っていく。人の彫刻でたとえれば、「頭、胴体、手足がどこにあるのか。どんなポーズなのか」を定める過程である。
この段階では、できるだけすばやく全体像がつかめるように作り、最初に思いついたアーキテクチャでいけるかどうかの判断をする。細部を作り込んでからアーキテクチャを変更することは不可能に近いので、この段階で徹底的な検証をする。
少しでも「何かがおかしい」と感じるのであれば、その理由を徹底的に究明し、必要であれば何度でも作りなおす。「せっかく書いたコードなのに」などとケチ臭いことを言ってはいけない。この段階で妥協すると、ほぼ確実にあとで後悔することになる。
トップクラスのソフトウェアエンジニアとそうでないエンジニアの違いを決めるのは、このフェーズだと言ってよい。使えないエンジニアは、この段階でのアーキテクチャの欠陥に気づかない、あるいは最初に思いついたアーキテクチャにしがみついてしまう。
私が詳細仕様書を嫌う理由は、まさにここにある。仕様書の作成に時間をかければかけるほど、それを捨てることが難しくなる。仕様書を書くとしても、まずはざっくりとしたイメージだけを「たたき台」として書いておき、必要に応じて仕様書にも大幅な変更を加える覚悟がなければ、良いソフトウェアはできない。
スタートダッシュとスケジュール管理
私の場合、この初期の「プロトタイプから骨組みの設計」の段階に全エネルギーを集中する。この段階で、良いアーキテクチャ、堅固な骨組みを作ることができれば、後がとても楽になる。
スケジュール感としては、本連載第2回で書いたとおり、「スタートダッシュの20%で一気に80%の完成度を目指す」というイメージで作る。それぐらいの気持ちで仕事をしていても、実際に達成できるのは50%の時間で80%の達成度だということを覚えておくとよい。
また、「ラストスパートをすると必ずミスをする」ということも覚えておくとよい。締め切りが迫った状況では良い仕事ができない。時間や余裕があるときにこそ、思いっきり集中して仕事をし、最後は余裕を持って流す、という仕事スタイルを徹底できれば、細かなスケジュール管理も不要になる。
ちなみに、スケジュールに関しては常に余裕を持って考えることが大切である。このプロジェクトの場合は、2012年4月初旬スタートで8月末のリリースという5ヵ月間の開発期間を見ている。リリース時に必要不可欠な機能の実装を終えた(function complete)のが6月末、ベータ版の一般ユーザへの配布を7月中旬に行った。最終版のアップルへの申請は8月中旬の予定で進めている。
頻繁なアルファリリース
このプロジェクトに関わるメンバーでコアになるのが、教育者としてのノウハウを提供する羽根さんと、それを実際にコードに落とし込む私、そして、デザインやテストで協力してくれる数人という構成である。
羽根さんには、仕様書などは書かず、とにかくアプリに持たせたい機能のアイデアをどんどんと投げてもらうように頼んでいる。
しかし、それだけだとなかなか具体的なイメージが固まらないし、プライオリティも定まらないので、プロトタイプの段階から頻繁に「アルファ版」を羽根さんにリリースして、フィードバックをいただきながら仕様を固めていく、という手法を取っている。
4~6月までの3ヵ月間、目に見える機能の追加ができるたびにリリースしてきたので、リリースの回数は50回を超える。週末も含めて2日に1回を少し超えるペースだ。
実質的には、このアルファ版が仕様書の役割を果たし、「ここは私のイメージと違う」「さらにこんな機能を実装してほしい」などのリクエストが羽根さんから上がってきて、それを受けて私が変更を加えたり、機能を追加したり、という作り方をしている。
当然だが、誤解や勘違いはどうしても生じるので、必要のない機能を実装してしまったり、羽根さんのイメージ通りに実装しても使い物にならないことが判明したり、ということも頻繁に起こるが、それも良いものを作るために必要不可欠なプロセスだと割り切っている。特にイメージの固まっていない初期の段階では「作っては壊し」というプロセスは不可欠なので、その段階でいかに効率良くフィードバックを反映していくかがプロジェクト成功の鍵を握る。
私がアルファ版を頻繁にリリースするのはまさにこれが理由である。1~2日で実装したものを作りなおすのは痛くも痒くもないが、2週間かけて実装したものを全面的に作りなおすとなれば時間の無駄だし、精神的なダメージも大きい。小さな変更を積み重ね、それに対してタイムリーなフィードバックをもらうことが大切だ。