特集
.NET開発者のための開発プロセス入門(前編)

アジャイル開発を導入できていない.NET開発者たちへ

福井 厚 & 小井土 亨
2004/11/20
Page1 Page2 Page3 Page4

アジャイル開発プロセスの導入

 .NET開発者がアジャイル開発プロセスを実践することはまったく不可能なのだろうか。開発者がアジャイル開発プロセスに魅力を感じていたとしても、現状に甘んじることしかできないだろうか。

■現状を踏まえたアジャイル開発プロセス導入

 この点について、筆者らはそうではないと考えている。外面的にはウォーターフォール型の開発を行っていても、開発者自身や開発チーム内では、アジャイル開発プロセスのいくつかのプラクティスを実践することは可能である。あるいはむしろ、外見上ウォーターフォール型のプロセスを受け入れながら、徐々にアジャイル開発プロセスのエッセンスを取り入れていくことの方が現実的ではないだろうか。

 例えば、単体テストの自動化やリファクタリングは、プロジェクトがウォーターフォール型であっても実践可能である。テスト・ファーストやペア・プログラミングと同時に行えばより効果的である。

 筆者の知っているある開発者は、アジャイル開発プロセスを進言したが上司に受け入れられなかったプロジェクトで、顧客や上司には内証でチーム内にXPの一部のプラクティスを導入して実践したそうだ。本来は朝に行うはずのXPのスタンドアップ・ミーティングを、顧客が夜帰宅した後に集まって行い、ペア・プログラミングをしている最中に上司が来ると、パートナーに技術的な問題について教えていたといってごまかしたそうである。

 この例のように、アジャイル開発プロセスに含まれる個々のプラクティスをミクロな開発プロセスと考え、開発者が実践可能なものから徐々に取り入れていく方法を、筆者らは「ローカル・ライトウェイト開発プロセス」と呼ぶことにした。

■ローカル・ライトウェイト開発プロセスのプラクティス導入

 ここからは、筆者らがローカル・ライトウェイト開発と呼んでいる、ウォーターフォール型開発にも導入可能なプラクティスについて、例を挙げて説明してみたいと思う。

◆単体テストの自動化

.NET用テスト駆動開発支援ツールNUnit 2.2の新機能(テスト駆動開発ツール最前線)
NUnit入門 Test Firstのススメ [NUnit 2.0対応版]

 まず、最初のプラクティスとしては、導入のしやすさという点で「単体テストの自動化」がよいだろう。ここでいっている単体テストでは、「プログラムをテストするためのコード」を記述し、テストの自動化を行う。このコードを実行する(つまり、プログラムをテスティングする)ための仕組みとして、XProgramming.comには、「xUnit」というテスティング・フレームワークが各言語用に用意されている。詳しくは後編で解説する予定であるが、.NETで開発を行っている場合は、「NUnit」というツールが利用できる。

 単体テストの自動化に際しては、いったん書いたテストは捨てないで取っておき、常にすべてのテストを実行し、テストを100%パスさせておくことが重要である。NUnitのテスティング・フレームワークを利用すれば、単体テスト全体を簡単に実行することができる。このように毎回テストを実行することで、バグを修正したときにほかの部分に影響がないかを常に確認することができ、勇気を持ってリファクタリングすることができる。

 開発現場によっては、システム・テスト(単体テスト、結合テストの後に行われる実運用環境に近い形のテストのこと)に比べて単体テストはプログラミングを行っている開発者に任せてしまっている場合も多いのではないだろうか。そのような場合、単体テストの自動化を行うかどうかはプログラミングを行っている開発者の判断に任されることになる。また、専用のテスターが存在するような場合でも、単体テストまでは手が回らないことも多いので、プログラミングの段階で自動化された単体テストを行うことには大きな意味がある。テストの自動化を行うことによって、コードの品質向上に非常に大きな効果が期待できる。

◆テスト・ファースト

 テストの自動化に慣れてきたら、次はテスト・ファーストに挑戦してみよう。

 テスト・ファーストでは、実装コードを書く前に単体テストを記述するのだが、それにはいくつかのコツがある。

 まず対象となるクラスを実装する前にテストを書く。先にテストを記述することで、これから実装するクラスがどのように利用されるかを想定することになり、クラスのインターフェイスを徐々に設計するような効果が生まれる。

 テストは最初に必ず失敗させて、作成したテスト用のプログラムが正しく動作することを確認する。テストを少し書いては、そのテストを通るようにテスト対象のクラスのメソッドを実装する。テストにパスするまで実装を行い、パスしたらまたテストを少し書く。テストと実装を少しずつ繰り返すことでテストの目的が明確になり、開発作業にリズムが生まれる。

◆リファクタリング

 テストの自動化(と、できればテスト・ファースト)を実践するとリファクタリングも可能になる。

 リファクタリングとは、外部から見た振る舞いを保ったまま、内部の処理コードを改善していく手法である。重複したコードをメソッドして抽出したり、共通のコードを基本クラスとして抜き出したり、インターフェイスを抽出して再利用性を高めたり、メソッドやフィールドの名前を変更してソースの可読性を高めたりする。リファクタリングを行うことで、理解しやすくメンテナンスしやすいコードに改善することが可能だ。

 リファクタリングを行ううえで重要なのは、事前に100%パスしているテストがあるということである。先ほどのテスト・ファーストのプラクティスを実践しておけば、これが可能となる。テストがあれば、リファクタリングにより誤って関係ない部分を変更してしまったり、バグを作ってしまったりするのを防ぐことができる。リファクタリングの最中にテストを実行することで、安全にリファクタリングを行うことができるようになる。

 リファクタリングもテスト・ファーストと同様に、プログラミングを行っている開発者の裁量で実践することが可能である。最初はコーディングのペースが落ちるのではないかと心配するかもしれないが、リファクタリングを進めることでコードの可読性が高まり、シンプルで保守しやすいコードを手に入れることができる。仕様変更や要求の変化は必ずといってよいほど発生するので、リファクタリングを行っておくメリットは非常に大きい。開発者の負担を低くするだけでなく、プロジェクト全体として考えた場合にも、結果的には工数を削減することにつながるだろう。

◆ペア・プログラミング

 次に、開発チーム内で実践可能なプラクティスをいくつか挙げてみたい。その1つが、ペア・プログラミングである。

 ペア・プログラミングは、ドライバとパートナーに分かれ、1台のマシンに向かって2人一緒に(ペアで)プログラミングを行う。ドライバはコードを書き、パートナーはドライバの横でそのコードを追いかけながら、気付いた点についてアドバイスを行う。ペアの役割は固定ではなく、頻繁にその役割を交代する。ドライバが行き詰ったときや、パートナーがここは自分がコードを書いた方がドライバに考えていることを伝えやすいと思ったら、自由にキーボードを取ってドライバを交代する。

 ペア・プログラミングのメリットは、常に2人でコードをレビューしているということだ。そのため、少なくとも2人はそのコードの内容を理解している。また、ペアは固定ではなく、ほかのメンバーと交代するため、結果的にチーム全員がコードの内容を理解することになり、誰でもコードをメンテナンスできるようになる。

 テスト・ファーストやリファクタリングのプラクティスを実行するときは、ペア・プログラミングで行うとより効果が高くなる。1人でプログラミングしていると、どうしてもテストが十分でない場合や、(テストのためのコードではなく)実装コードばかりを記述してしまいがちであるが、ペアでやっていればパートナーが注意してくれる。リファクタリングを行っているときも、お互いに会話しながら行うことで、リファクタリングの目的を常に意識することができる。

 ペア・プログラミングを行うには、開発チームの理解が必要になるので、開発チーム内でペア・プログラミングの効果について話し合い、相互に理解する必要がある。プロジェクト・マネージャや管理職からは、生産性の低下を心配して反対の声が上がるかもしれないが、これに対しては、書籍『XPエクストリーム・プログラミング アドベンチャー』(ウィリアム・C・ウェイク著、ピアソン・エデュケーション発行)の第4章を示して説明するか、Alistair CockburnおよびLaurie Williamsの「The Costs and Benefits of Pair Programming」を読んでもらい理解を促せばよい。それでも駄目なら、先ほどの例のように、あきらめて上司に内証で行うということになるかもしれないが……。

◆常時結合

 ペア・プログラミングは難しくても、常時結合のプラクティスは実践できる可能性がある。

 常時結合は、アプリケーション全体を1日に何回も結合することにより、常にシステムをエラーのない状態に保っておくという手法である。各開発者はソース・コード管理ツールを使ってネットワーク上にあるリポジトリに、単体テストをパスしたコードをチェックインし、NAntなどの自動ビルド・ツールを使ってシステム全体をビルドしてから、すべての単体テスト、受け入れテストを実行する。ここでエラーが発生した場合は、それまでは100%テストが通っているので、自分のコードがほかの部分と整合性が取れていないということになる。エラーが発生した場合は、エラーの個所を確認して修正を行い、テストをすべてパスさせる。

 このようにシステムを常に結合することによって、リグレッション(回帰)バグがないことを確認でき、システムが常に整合性を保っていることを保証することができる。

◆そのほか

 そのほかにも、コードの共同所有やコーディング規約、スタンドアップ・ミーティングなどのプラクティスもプロジェクトに取り入れることが可能だろう。

 また、顧客側の企業で常駐して行うようなプロジェクトの場合には、オンサイト・カスタマーと同等のプラクティスを実践できる可能性がある。つまり、常に発注側の顧客とコミュニケーションを取り、頻繁に内部的なリリースを行い、顧客に実際にシステムに触れてもらうことで、適切なフィードバックを得ることが可能となる。

 ぜひ工夫してアジャイル開発のプラクティスに取り組み、アジャイル開発プロセスのメリットを生かすようにしていただきたい。

 後編では、このローカル・ライトウェイト開発プロセスについて、NUnit、NAnt、NMockなど.NET開発者が実際の開発現場ですぐに使えるツールを交えながら、より具体的に紹介する予定である。End of Article


 INDEX
  [特集] .NET開発者のための開発プロセス入門(前編)
    1.アジャイル開発プロセスが誕生するまで
    2.アジャイル型開発プロセスとは何か?
    3..NET開発者がアジャイル開発プロセスを導入できない理由
  4.アジャイル開発プロセスの導入
  [特集] .NET開発者のための開発プロセス入門(後編)
    1.1人からでも導入可能なローカル・ライトウェイト開発プロセス
    2.単体テストの自動化とテスト・ファースト
    3.Mockオブジェクトとリファクタリング
    4.数名のチームで導入できるローカル・ライトウェイト開発プロセス
 


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間