プロジェクトを成功させる上で、重要なのは、工数管理です。工数を正確に見積もり、スケジューリングし、また機能追加や修正要求に対して適切に対応することです。不確定な要素が多い中で、プロジェクトを期間内に成功裡に終わらせるのは、奇跡に近いものがあります。
プロジェクトの失敗の多くは、工数管理ができていないことにあります。
など、プロジェクトの進捗を妨げる多くの要因があります。
なかでも、工数の過小評価は重大なものです。見積もりの段階ではざっくばらんに見積もってしまうため、実際プロジェクトが始まってみたら作業量は数倍になんてこともあります。また簡単にできると思われたことが、プラットフォームや使用するアプリケーションサーバーの制約でできず、遠回りの方法適用しなければならないとかという場合もあります。技術の調査のために、時間がかかる場合もあります。
工数は人月単位で出ます。12人月と言ったら、要員3人で4ヶ月かかるという意味です。これはお金の計算にも使われる単位です。
この場合、4人投入して納期を3ヶ月にすることはできるでしょうが、12人費やしたからといって1ヶ月で済むわけではありません。人が多ければそれだけ管理と教育に時間がかかります。そこを勘違いして早く終わらせようとして人を投入するのはプロジェクトを混乱させるだけです。
通常、要件定義・設計、開発、テストとスケジュールを組むのですが、だいたい開発でもたつくことが多いのです。そうするとテストフェーズに入ってもまだ開発を続け、テストフェーズを短くしてしまうのです。確かにテストは順調に進めば、テスト期間は短く進みます。しかし、もたついた開発でテストがスムーズに行くことは考えにくいことです。無理にテストフェーズに突入してもバグの嵐となります。大概必ず何らかのバグは出るものです。テストフェーズとはテスト手順を実施して動作を確認するフェーズではありません。テスト+デバッグ作業です。そして修正した後は再度テストします。ユーザのテストとなると、バグが出なくても仕様の食い違いにより必ず修正要求が出ます。この辺を考慮してテスト期間を考える必要があります。
かといって、余裕のあるスケジュールも問題で、要員がマイペースでゆっくりと開発を進め、納期直線になってあたふたすることもあります。どんな開発でも、自分が思い描くより倍以上手間がかかると考えた方が正解です。
こういう欠点を防ぐために出て開発方法論が、プロトタイプやスパイラル、インクリメンタルといった方法論で、早い時期にユーザーに製品を確認してもらい、またリリースを細かく分けることでリスクを回避するのです。
また、要員のスキルの評価も大きく影響します。優秀な人間が3日でできることを、スキルの低い人は1月かかり、しかもバグありのものを提供します。できると思っていたが、当てが外れるとか、経験1年の者を頼んだつもりなのに初心者が来たなど、いろいろあります。
また、コロコロ意見の変わる客も要注意です。自分で無理難題を押し付けていながら、できないと怒り狂う客もいます。客だということで大きな態度で、あれこれ注文をつけて来る人もいます。受ける側は客を怒らせまいとして、ハイハイということを聞いてしまいます。理解ある客でないと、大概苦労します。曖昧で方針が決まっていないのに注文してくる客は、途中でコロコロ意見を変え、そのたびに惑わされます。
また性能要件は要注意です。SLAの中に、レスポンスタイム、スループットを正確な数値で要求するものがあります。この辺は経験がないと難しいです。先にタイムありきだと、かなり苦労し、どう頑張っても、それだけの性能が出ない場合があります。速度はハードウエアに依存するため、そういうハードウエアを開発中に用意できないときついですし、またすでにそのハードウエアを使ってどれだけの性能が出たのか知らないと計算はできません。
またどれだけロジックを工夫しても時間がかかるものはかかります。特にデータウエアハウス系の分析処理で複雑なものは、瞬時にレスポンスが返ってくるなどと期待してはいけません。
また、性能要件は開発のなるべく早い段階で計測できるほうが望ましいです。通常、システムテストの中で性能測定を行うのですが、そこで行うのは遅すぎるのです。その段階で負荷をかけてみて全く性能要件を満たせないとわかって、結局、根本的なアーキテクチャーを見直す必要が出てきて、修正するのにシステムのあちこちに影響が出て、修正に膨大な時間がとられることになります。
昔、レスポンスタイムは0.1秒と馬鹿の一つ覚えのように唱える頭の固い上司がいましたが、処理によって速度は異なるので、一律何秒と決めることはできないのです。
もし明確に秒数が決まるのなら早めにボトルネックになりそうな部分を調査する必要がありますし、その調査結果が出ないのであれば、要件定義にコミットしない方がいいのです。
以前勤めていた会社で、社長が何の根拠もなく、サーバーの性能を発表してしまったおかげで、ひどく苦労を強いられたことがあります。
もし性能要件だけではなく、信頼性などもSLAとして品質保証を行う場合、作成側はかなりのリスクを負うことになるので(テスト工数もかかります)、工数は倍は見積もっておく必要があります。というのもハードの選定にもかなりの工数を要します。数字は騙せないので、下手なコミットはしないほうがいいでしょう。ソフトを販売しているだけなら、客が手に入らないようなマシンで、好条件下で、性能を測定してごまかすことはできるでしょうが。
仕様の中に矛盾がある場合は実装では解決できません。また複雑な仕様からシンプルな実装は生まれません。実装は仕様よりも複雑になります。なので、仕様を整理し、無駄をなくすことが重要です。
使いもしない、もしかしたらというのをできるだけ排除しましょう。実装では、拡張の可能性を残しておきながらも、仕様には盛り込まないことです。仕様に含めれば、テストしなければなりません。テストの工数は馬鹿になりません。
システムの目的をはっきりさせ、余計なところは削ることです。システムの使い方がはっきりしないユーザは、あれもこれもできるようにと可能性を残しておきがちです。その場合に言うべき常套手段は、「第一フェーズでは、これだけにしておきましょう。次のフェーズで実装しましょう」です。
拡張性のない設計・実装をしていると、機能が追加されたときに、根本から作り直すか、回りくどい処理を追加しなければならなくなります。後者の場合、そのたびにソースが汚くなり、それが続いた場合には、スパゲッティと化します。
とはいえ、ここは永遠に解答の出ない問題でしょう。どんな追加・修正にでも対応できる設計などありません。汎用的に使えるものというのは作成が難しいし、その上に作りこむ実装は、その要件にだけ対応したものを作るのに比べて厄介です。テスト工数もかかります。最初の設計の段階で決めた枠組みに収まる変更ならいいのですが、その枠組みでは対処できない問題となると、根本から作り直さなければなりません。そのときに批判するのは簡単です。どうしてその部分を変更できるような仕組みにしなかったのかと。しかし、プログラムを作る場合、どれかは枠組みとして固定しなければならないのです。
しかし、何でもできる、何でもカスタマイズできるとなったら、結局新たな言語を作り出すのと変わりなくなり、設定ファイルがプログラミング言語のようになってしまい、問題は何も換わっていないことになります。これまたテストに時間をとられます。
ここで登場するのが、リファクタリングの考え方でしょう。XPでは、先の拡張のことは考えず、できるだけ最適に作るのです。使いもしないものは作りません。修正が入れば、抜本的修正であってもその都度直します。ただしそこで起きるデグレードの問題を解決するために、テストの自動化を導入します。