前回(「ビルドはどのような要件を満たすべきか」)は、ビルドが満たすべき要件について説明しました。今回は、どのように反復を計画すべきかを説明します。
反復を計画するとは、つまりビルドのリリース計画を立てることです。ソフトウェア開発を反復型で計画するときには、必ずこの中にビルドのリリース計画が含まれていなければなりません。ビルド計画書とは、例えば次のようなものです。
ビルド | QAリリース | 顧客リリース | |
build 1 | 2004/04/16 |
-
|
-
|
build 2 | 2004/04/30 | 2004/05/03 |
-
|
build 3 | 2004/05/07 | 2004/05/10 |
-
|
final(rc) | 2004/05/14 | 2004/05/17 |
-
|
release build |
-
|
-
|
2004/05/24 |
表1 ビルド計画書の例 |
ここに例示した計画書は、およそ2カ月で開発するソフトウェアをweeklyで反復しながら開発する例です。毎週ビルドを立てる場合には、ビルドする曜日を決めると非常にやりやすくなります。海上自衛隊は週間の感覚を失わないように、金曜日をカレー曜日として、必ず週に1度カレーを食すそうですが、それと微妙に似ているかもしれません。
上の計画書でも、金曜日をビルド日として、月曜日をQAへのリリース日として計画しています。このようにすることで、現在開発しているビルドがいまどういう状態なのかを、チームの全員が把握し、共有しやすくすることができます。例えば、毎週金曜日をビルド日として設定した場合には、毎週木・金曜は毎度おなじみの修羅場になるということです。
ウォーターフォール型の開発プロセスでは、結合テストの時期にはひと月の間、毎日修羅場になることも珍しくありませんが、反復型の開発ではこのリスクを時間的に分散させて、リズムを作ります。また、各メンバーが自分の作業のゴールやマイルストーンをビルドごとに設定できるので、見通しが良くなります。
このとき、各ビルドで何を実現するのかを決めておかないと、開発が予定どおりに進んでいるのかどうかを検証することができません。従って、どのユースケースをどのビルドで実現するかを決めておくとよいでしょう。例えば、次のような計画書を記述します。
機能の概要 | 実装予定ビルド# | 実績ビルド# | 担当者 | |
UC1 | 文書を作成する | build 2 | TBD | 津田 |
UC2 | 文書を保存する | build 2 | TBD | 津田 |
UC3 | 文書を応募する | build 3 | TBD | TBD |
UC4 | 文書が落選する | build 3 | TBD | 津田 |
表2 各ビルドで何を実現するのかを決めておく |
ソフトウェアのドメインによっては、上のようなユースケースに基づく単純な計画書にはならないかもしれません。しかし、何らかの形で、どのビルドでどこまでの機能を実現するかを決めておくことが必要です。もちろん、反復を繰り返すごとにユーザーの要求が変化してしまうことがあるので、最初の段階から完全な計画を立てることは困難ですが、少なくともあるビルドをリリースするときには、そのビルドで何を達成するつもりなのかが決まっていなければなりません。本当に達成できたかどうかは、このビルドのリリース後に、QAが検証することになります。
ビルドをリリースする計画を立てることで、ソフトウェア開発に付随するほかの計画もすべてビルド番号で行うことができるようになります。この機能制限を解除するのは「何月何日までに」ではなく「どのビルド#までに」、この不具合を修正するのも「何月何日までに」ではなく「次のビルドで」、このサブシステムのテストを開始するのも「何月何日から」ではなく「どのビルド#から」、といった具合です。反復の「単位」がビルドであることが、理解していただけるのではと思います。
ソフトウェアの開発計画を丁寧に月日で立ててみたけど全然予定どおりにいかなかった、という経験をお持ちの方は、ぜひ一度ビルドを単位として開発計画を立ててみることをお勧めします。
XPのスローガンに「変化を受け入れよ」というものがあります。この言葉は誤解を招きがちですが、決して「最終ビルドをリリースするまでは、どんな変化であれ、受け入れるべきだ」というわけではありません。仕様がコロコロ変わっていては、各ビルドで何を検証していいか分からず、テストの計画も立てようがありません。それはただの手戻りであって、反復的な開発とは違います。もちろん、最初にすべての仕様をフリーズするべきだ、といっているのでもありません。変わりにくい(と思われる)部分から、段階的に仕様をフリーズしていくべきなのです。フリーズできた仕様から順に実装し、このアウトプットであるビルドを次のビルドのインプットとして、さらにほかの仕様をフリーズしていくのです。最後までフリーズできなかった部分は、アプリケーションの可変点として残し、これをパラメータ化することができれば理想的です(もしくは、理想論ですが)。このようなアプローチは、反復的(iterative)というよりも漸増的(incremental)といった方が用語としては適切かもしれません。
ビルド計画を立てる際には、重要なポイントがいくつかあります。このいくつかを以下に紹介します。
まず検討すべきなのはこれです。最初のビルドは、アーキテクチャの妥当性や期待したパフォーマンスが出せるかどうかなどを検証することになる重要なものとなります。これをいつ出す(出せる)かが、その後の作業に大きく影響します。もちろん、アーキテクチャがいけてなかったり、パフォーマンスが出なかったり、ということになれば、2番目のビルドの位置付けを最初のものと同様のものに変更して、スケジュールはひき直しとなってしまいます。
もっとも、自社にとってあまり技術的なノウハウがないソフトウェア開発プロジェクトの場合は、それを織り込んだ形でビルド計画を立てるべきでしょう。
このほか、最初のビルドには、構築した開発環境とビルド環境の妥当性を検証し、以後の反復をスムーズに行えるようにするという重要な役割もあります。特に、組み込みソフトウェアの場合には、ハードウェアや開発環境の変化が開発作業に影響するので、これらを早い段階でチェックしておきたいところです。
前述したように、最初のビルドでは非機能的な部分を検証することが多いので、テストケースに基づいたテストが行えないこともしばしばです。そもそも、最初のビルドのリリースまでにテストケースが用意できないことも多いため、最初のビルドはQAよりも開発者がテストする方が合理的です。従って、規模が大きな開発では特にそうですが、開発の初期の段階から多人数をプロジェクトに投入することが間違っていることがあります。どのビルドからQAチームに開発に参加してもらうかを検討しておくとよいでしょう。
また、ソフトウェアのテストは、その仕様をよく理解している人が行うのが一番です。この観点から、要求仕様を獲得する役割のチームを編成するプロジェクトでは、このチームがQAも担当すると良い結果を生むことがあります。逆にいえば、要求仕様を獲得して仕様書やテストケースを記述するために、QAチームが開発の最初の段階からプロジェクトに参加する、ということです。この場合は適切な人員を適切なタイミングで確保できるかどうかという制約も考慮しながら、どのようにプロジェクトチームを編成するか決めるとよいでしょう。
最初のビルドをリリースした直後から、定期的にビルドをリリースするのが難しいことはよくあります。このあたりも、開発するソフトウェアのドメインによって最適なパラメータが異なってきます。ただし、反復型開発を初めて試そうという方は、ビルドをリリースする頻度については1週間を強くお勧めします。
仕様(機能)を凍結することをfeature freezeといいます。もちろん早くにfeature freezeした方が、開発期間をオーバーしてしまうかも、というリスクを低減できます。が、プロジェクトメンバーが顧客のドメインに疎い場合、feature freezeを早い時期に設定し過ぎると、役に立たないものが出来上がってしまうかもしれない、というリスクが高まります。が、そのリスクを低減するために、開発途中のビルド(マイルストーンビルド)を何度か顧客にリリースするようにしたら、今度は顧客からの仕様変更要求により、予定していたビルドでfeature freezeを行うことができなくなるかもしれない、というリスクが高まります。が、そのリスクを低減するために、開発期間を長めにとったら、競合他社に負けて顧客が自社に発注してくれなくなるかもしれない、というリスクが高まります。
要するに、feature freezeするために必要十分な時間を正しく見積もってビルド計画を立てる必要がある、ということです。
仕様を完全に凍結した後も、実装と不具合の修正の作業を完了させるために、何度かビルドを出すことになります。feature freezeの後に、何回くらいビルドを出すことになるのか見積もることができなければ、プロジェクト全体の見積もりも精度の高いものにはなり得ません。予定していた開発工数や予算をオーバーしてしまうことになります。もっとも、これを正確に見積もるのは難しく、経験が頼りです。
feature freezeした部分を実装できたからといって、即その部分のソースコードを凍結する、というわけにはいきません。feature freezeはインクリメンタルなアプローチを取るのが望ましいのですが、ソースコードは明確にどの範囲をフリーズする、といったことが難しいため、より反復的なアプローチによる恩恵を享受するという姿勢でいた方が良い結果を得られるでしょう。
つまり、ビルドのリリースを繰り返しながら、問題のある実装部分をリファクタリングし、きれいに書き直していく(あるいは、駄目なコードを全部捨てて、最初から書き直していく)ということです。
もちろん、凍結したつもりの仕様でも、後で使えないことが判明したら全部捨てて書き直さざるを得ないこともあります。こういうときは、「われわれはiterativeな開発をしているんだ。変化を受け入れよう!」と心で泣きながら、自分を納得させるとよいでしょう。
しかし、最終ビルド候補をリリースするときには、すべてのソースコードを凍結することになります。いつ、code freezeをするかは明確に意識すべきです。コードフリーズした後は、いかな不具合も直すことはできなくなってしまいます。また、コードフリーズの後はリグレッションテストという一大イベントが待ち受けています。
開発するソフトウェアのドメインによっても異なるでしょうが、おおよそ以上のことを意識・考慮しながらビルド計画を立てれば大丈夫!
次回は、ビルド環境の構築について説明します。お楽しみに。
この記事に対するご意見をお寄せください
managemail@atmarkit.co.jp
▼津田義史
5年間、某外資系ソフトウェアベンダでパッケージ製品の開発とグローバリゼーションに従事。その後、オブジェクト指向技術に疑問を感じ、2000年に豆蔵に入社。現在は、コンサルティングを通して、間違った開発プロジェクトをみることが多く、改めてソフトウェアというものが難しい仕事であることを実感する毎日。興味の対象は、C++のテンプレートを使った静的な多態性の活用だが、最近はC++のコードを書く機会そのものが少ない。
Copyright © ITmedia, Inc. All Rights Reserved.