« Mercurial チュートリアル hginit.com の和訳のリンク | トップページ | 課題管理のチケット駆動開発 »

2010/05/05

Agile開発が指摘したソフトウェア開発の特徴

Redmineによるチケット駆動開発を通じて、Agile開発の利点や特徴、その弱点も少しずつ理解できてきた。
今後の進化の方向も含めて考えてみた。
以下はあくまでもラフなメモ書き。

【1】現代のSW開発マネジメントは、従来の品質・コスト・納期の三角形から、スコープ・コスト・納期の三角形に変わっている。
この事実は、現代では納期(Deliveriy)の重要性がすごく高まっていることを示唆している。
実際、3ヶ月後の景気すら分からない状況で、数年越しのプロジェクトを実施するビジネスは非常にリスキーになっているからだ。

Agile開発は、WF型開発よりも納期重視の開発スタイルと言える。
Agile開発の開発スタイルは、XPのイテレーション又はScrumのスプリントというタイムボックス単位で順次リリースしていく戦略をとる。これは、納期が2~4週間後に定期的に決まっていて、チームメンバーは数人で固定するからコストも決まっているから、システム要件と言うスコープを変化させてバランスを取ろうとする手法。

この手法はXPの計画ゲームから生まれたと認識しているが、ScrumはこのXPの計画ゲームをより厳密に運用しやすいマネジメント手法として最近は広く普及している。
Scrumの各種の技法の中で最も重要な概念の一つは、バックログという考え方だと思う。

バックログは、システム要件を書いたストーリーカードの貯蔵庫。
顧客からの要望はバックログへ一旦貯蔵し、実装方法やコストを吟味したり、ビジネス上の重要度や作業の優先度を考慮したりして、どの要望を最優先に開発するか、ふるいにかける。
そして、リリース計画あるいはスプリント計画を作る時に、開発する対象のストーリーカードをバックログから取り出して、スプリントにアサインし、スプリント期間中に開発して、リリースする。
つまり、バックログという貯蔵庫があるからこそ、要望のフィルタリング、要望のトリアージが可能になるのだ。

この発想は、リーンソフトウェア開発にある特徴「決定をできるだけ遅らせる」に似ている。
すなわち、必要になった時にバックログから要望を取り出してくればよいのであり、そうでなければ、すぐに判断を下す必要はないのだ。

バックログと言う発想は、Scrumだけでなく、TestLinkのテスト仕様にも同様の概念が見られることに注意したい。
つまり、バックログは意思決定時の取捨選択において重要な技術の一つと言える。
バックログがあるからこそ、柔軟な意思決定が可能になるのだ。

納期重視の開発スタイルが可能になった背景には、Webシステムのようにリリース作業はサーバーにデプロイするだけだったり、組込製品のソフトウェアアップデート機能のように簡単に後からソフトウェアを更新できる仕組みが普及しているからだ。
例えば、iPodや携帯電話も、製品を購入後にソフトウェアを更新できるだけでなく、ROMさえも更新できるのだ。
つまり、致命的な障害でない限り、そこそこの品質が保証されていれば、早くリリースした方がビジネス上優位に立つという現状があるのだろう。

【2】Agile開発の全ての技術、そして発想は、XPのプラクティスである小規模リリースで全てを説明できると思う。
つまり、ソフトウェア開発はVerUpしながら機能拡張していくのが最善なのだ、という主張が込められているように思う。
逆に言えば、VerUpしないソフトウェアは無価値。
どんどん機能拡張されないソフトウェアはすぐに陳腐化されてしまう。

そして、この主張を実現するには、頻繁にリリースできる技術を持つことが前提になる。
しかし、頻繁にリリースするのはとても困難なのが実情だろう。
現代のAgile開発でも、XPやScrumでさえも2~4週間の開発サイクルは必要としている。
リーンソフトウェア開発のように毎日リリースできる開発スタイルは理論上成り立つけれども、実践するのは不可能に近いのが現実だろう。

この前提条件を満たすために、テスト駆動開発、継続的インテグレーション、ソース共同所有、リファクタリング、シンプルなどのXPのプラクティスがあるのだと言える。
これらXPのプラクティスを見ると、Agile開発はソフトウェア構成管理(Software Configuration Management)を重視していると読み取れるように思う。

ソース共同所有のおかげで、誰もがいつでもソースを取得してパッチを当てることができる。
更に、テスト駆動開発によって単体テストの品質は最低限保証され、継続的インテグレーションによって、メインライン(trunk)は常時リリース可能な品質を維持できる。
これらのインフラがあるからこそ、頻繁にリリースできるのだ。そうでなければ、リリース作業の間隔を短くするのは難しいはずだ。

【3】複数の機能を常時統合するアイデアから継続的インテグレーション(CI)のプラクティスは生まれた。
システムが大規模になるほど、コンポーネントを結合する時に初めて重大な問題が現れやすい。
全てのモジュールを別々に並行して作って、進捗を早めるのは良いが、結合する時にビッグバンテストを行うと、たくさんの問題が噴出して制御できない時が多い。
だからこそ、部品(コンポーネント)を少しずつ結合して早めにビルドする方がリスクヘッジができる。
そして、その作業は自動化してしまえばいい。
自動化できれば回帰テストが可能になるから、デグレを早期に発見することもできる。

しかし、継続的インテグレーションが有効な範囲は実は限られる。
実践アジャイルテスト テスターとアジャイルチームのための実践ガイド (IT Architects’Archive ソフトウェア開発の実践)」にあるアジャイルテストの4象限では、継続的インテグレーションが有効な範囲は、第1象限の単体テストと第2象限の機能テストだけだ。
第3象限の受入テストや第4象限の負荷テストは、従来の発想だけでは、継続的インテグレーションやテスト駆動開発が有効でない。
何故なら、受入テストや負荷テストは自動化するが難しく、テスト環境が高価な上、それらのテストを実行したら数日もかかってしまう時があるからだ。

つまり、「アジャイル開発は開発環境ではとても有効だが本番環境ではその恩恵があまりない」という指摘は「ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション」において「ラストマイル問題」として既にあげられている。

だが、このラストマイル問題に対しても、最近の技術を上手に使えば解決できるだろうと思う。
本番環境が高価で作ることさえ難しいという問題は、VMWareのような仮想化技術で解決できるだろう。実際、一度環境を作れば、最近のHDDやメモリ、サーバーはとても安価なので、その仮想イメージをいくらでも複製すればいい。
そして、実際のテストが複雑で工数もかかるという問題は、ビルド管理ツールHudsonで並行ビルドすればいいと思う。つまり、本番環境の複雑なビルド作業をHudsonの複数のジョブへ分割して、並列に実行すればいい。そうすれば、見かけ上のビルド時間は半減されるはず。

最近は、RedmineやTracのようなプロジェクト管理ツールに目が行きがちだが、Hudsonにはアジャイル開発の作業の自動化に最も大きなポテンシャルを持っていると思う。
Hudsonに関する情報がネット上も少ないのは残念。

【4】アジャイル開発の構成管理に関わる技術として重要なのは、並行開発を支える構成管理技術と分散バージョン管理だ。
アジャイル開発が難しい理由の一つは、アジャイル開発は実は二つ以上のコードラインを常時保守せざるを得ない並行開発である認識がないからだろうと思う。
アジャイル開発の最重要なプラクティスである小規模リリースを実践すると、一度リリースしたコードラインを保守する作業と次のイテレーションで機能追加していく作業の2本が発生する。つまり、一度リリースしたらシステムはそれでお終いというわけではないのだ。
だから、一つのコードライン上で機能追加と障害修正を混ぜ込んでしまい、いつまて経っても品質が安定しない時が多いのだろう。

この問題に対する解決法としては、trunkとリリースブランチで分けて作業するメインラインモデルがある。つまり、リリースしたらリリースブランチ上で障害修正を施し、trunk上で機能改善していく構成管理技術を指す。
これによって、障害修正と機能改善のソースを別々に管理できるので、ソース修正の影響を限定でき、品質を確保しやすくなる。
しかし、ブランチが増えるほどマージ作業が増えて、ソースの最新化が難しくなる。

だが、分散バージョン管理を使うと更にトピックブランチという開発手法が使える。
この手法は「入門Git」で詳しく説明されているオープンソースではよく知られた構成管理技術。
マスターリポジトリから別のブランチを作り、一つのトピックに対するパッチをこのブランチ上で実験する手法だ。
SVNの場合、トピックブランチで作ったパッチは一度Diffを出力して手作業でマージするしかないが、MercurialやGitなら、リビジョンを指定してPushやPullを使えば、自動的にマージできる。
トピックブランチはメインラインモデルの発展形と言えるのはそれが理由だからだろう。

【5】これらの手法を通じて分かることは、アジャイル開発では特に移植性や保守性を重視していることだろう。
納期を重視するからこそ、少ない工数で開発せざるを得ないから、移植性や保守性という品質が特に重要視されているのだろうと思う。

既成のシステムへ機能追加するには、保守性が高くなければ、機能追加する以前にリファクタリングの工数がとてつもなく大きくなる。デグレしないために品質を保証する作業がとても大変なのだ。

更に、既に成功したシステムを基盤として派生した製品を作り出す場合、移植性が高くなければ、又一からスクラッチで開発せざるを得ないから、コストも工数も膨れ上がる。かと言って、戦略もなしにソースをコピペすると、オリジナルのシステムがVerUpした時に、最新ソースを取り込むのが難しくなり、派生した製品なのに独自発展した製品系列になってしまう。

保守性を重視する開発スタイルは、XPならリファクタリングやシンプルというプラクティスで既に実現されている。
しかし、移植性を重視する開発スタイルは、XDDPのような派生開発ソフトウェアプロダクトラインのような製品ファミリー開発のようなノウハウが必要になってくるのだろうと思う。

|

« Mercurial チュートリアル hginit.com の和訳のリンク | トップページ | 課題管理のチケット駆動開発 »

プロジェクトマネジメント」カテゴリの記事

Redmine」カテゴリの記事

ソフトウェア工学」カテゴリの記事

廃止Mercurial」カテゴリの記事

構成管理・Git」カテゴリの記事

チケット駆動開発」カテゴリの記事

Agile」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



« Mercurial チュートリアル hginit.com の和訳のリンク | トップページ | 課題管理のチケット駆動開発 »