アジャイル開発の組織論としての側面

マイクロソフトの「Agile Day 「A Start - アジャイル開発が気になるあなたに贈るセッション&ワークショップ」(ここの2010.01.22のイベント)に参加したり、
すくすくスクラムの「1月25日 第8回すくすくスクラム ~1人1人が、リーダーだ!~(東京都)」をustreamこれ)で見たりして、これまでアジャイル開発について持っていたイメージがちょっと変わってきた。

これらに触れる前までは、開発方法論としての側面しか見えてなかったけど、どうもマネージメント論や組織論という側面があるように思えてきた。

というのは、アジャイル開発では開発メンバが本当のチームとして協調して自律的に動く必要があって、これまでのプロジェクトマネージャを中心としたピラミッド構造のチームとはそのありようが全く異なる気がするのだ。

ちょっと前に『ヒトデはクモよりなぜ強い』という本が出ていたけど、
アジャイルな組織はヒトデ型っぽくて、
ウォーターフォールな組織はクモ型っぽいんじゃないだろうか?

本読んだらまた書く。

ヒトデはクモよりなぜ強い

ヒトデはクモよりなぜ強い

NetBeansのMavenプロジェクトでデバッガ(jdwp)が使えなくなった場合の対処

cnaos2010-01-30

はまったけど、いちおう解決することが出来たらしいので書いておく。

結論から言うと、maven-surfire-pluginのバージョン2.3から2.5に上げるだけ。

デバッガの接続に失敗した際に表示されるエラーメッセージは次の通り。

Have no FileObject for C:\Program Files\Java\jdk1.6.0_18\jre\lib\sunrsasign.jar
Have no FileObject for C:\Program Files\Java\jdk1.6.0_18\jre\classes
Error occurred during initialization of VM
agent library failed to init: jdwp
ERROR: Cannot load this JVM TI agent twice, check your java command line for duplicate jdwp options.
Java Result: 1
debug-test:
構築成功 (合計時間: 0 秒)

現象的には、Bug 166968 – Debugger throws error on startup: Cannot load this JVM TI agent twiceと同じだと思われる。

発生を確認した条件はつぎのとおり


で、プロジェクトのpom.xmlにあるmaven-surefire-pluginのバージョンを「2.3」から「2.5」に上げたら解決した。

NetBeansをアンインストールしたりするなど試行錯誤して、対処方法を見つけることが出来たのは本当に偶然だった。

昨日(1/22)MicrosoftのAgile Dayに行ってきた

皆様お疲れ様でした。

イベントレポートって何をかけばいいんだろ?とりあえず、個人的な感想とふりかえりを中心に書きます。
また、勝手な解釈が混じっている事を先にお詫びします。イタリック青字の部分は私の考えなどです。

見た感じ、スーツ率高い、参加している人はプロジェクトリーダ/マネージャが多いみたい。また、実際に現場でアジャイル開発に取り組まれている方が多いような感じがしたけど、実際のところどうだったんだろう。

私の立場

セッションごとに印象に残ったこと

セッション1:アジリティを向上させるためにマイクロソフトが行ったこと〜Visual Studio 開発部門の場合〜

長沢さんのセッション。マイクロソフトでのアジャイルな取り組みについて。
大規模な製品開発(VisualStudioの開発)にアジャイルを取り入れた事例の紹介。
ちょっとまとめきれないので、印象に残ったところだけ書き出したけど、ヒントがいっぱい詰まっていそう。

  • VisualStudio2008の開発では新規開発を中断し、既存バグの根絶に集中した。
    • 標語は"Get Clean, Stay Clean"
    • ジョエルテスト#5「新しいコードを書くまえにバグを修正するか?」に通じる話。
  • リスク報告の正直さHonestlyが大事
    • 大雪のためスケジュールが遅延するなんて事まで書いてある。

TeamFoundationServerってどんなツールなんだろう。

セッション2:「開発現場でのムダ取り・改善活動」

三井さんのセッション。
アジャイルの成功事例をベースに、どういった改善活動をおこなったのかを紹介。

最新のIID手法では、開発構想書および「概要レベル要求のトップ10」一覧の作成や、負荷やユーザビリティや多言語化といったアーキテクチャに大きな影響を及ぼすような要因の分析を、早い段階でベースライン化するよう推奨している。

  • 問題が起こったとき、「お前なにやってんだよ!」ではなくて、「ちょっと教えてくれる?」で情報を引き出す。
    • セッション1で出ていたリスク報告の正直さを保つために必要な態度だろう。
    • たとえば、指先に熱いものが触れていて、それが脳に報告されなかったら、大やけどする。
    • 神経が正直に情報を伝えるから反射的に手を引っ込めることが出来る。
    • リスクを見逃さないために正直さがプロジェクト必要なのかも。
    • 怒れるマネージャはもらいが少ない。

セッションの内容ではないけど、懇親会の時に聞いた、受託開発でのアジャイル成功事例はおもしろかった。ドキュメンタリーとして読みたい。

  • アメリカのアジャイルは、自社内開発がメインなので、日本の受託開発にはそのまま適用できない部分がある。
  • プロダクトバックログの戦略的な選択。
    • およそ全体の4割程度のコアな機能を、顧客とのアーキテクチャレビュー時にデモンストレーションしたなど。
セッション3:「あなたにとって、アジャイルとは何ですか?」

江端さんのワークショップ。
アジャイルは押しつけではうまくいかない。プロジェクトメンバーが自律的に動かないとうまくいかない。
ということで、「自律的に考える」、「改善するにはどうしたらよいかを考える」といったことを体感するワークショップだった。と都合良く解釈する。

「このワークショップの目的=ゴールは何か」を明らかにした方が、参加者が自律的に考える手助けになって、もっと良くなったかも。

現場や開発チームにいるのも人。
ソフトウェアを利用するのも人。

仕事で開発すべきことも人に繋がっている。

人から目を離し、人を無視しても価値を生むことはできない。

問題の原因はツールや技術ではなく人間に依存する。

    • 「ソフトウェアを作るほとんどの工程には人間が関わっている。だから、いかにヒューマンエラーを減らすかがムダを削減するために重要になってくるのではないか。」という持論に通じるものがあった。
    • ピープルウェアを読み直してみよう。

ワークショップでの「アジャイルとは何か?」という問いのメモを公開してみる。

  1. 最初の質問「アジャイルとは何か?」
    • 自律的
    • 適応的
    • 早いフィードバック
    • ムダを少なく
    • ちゃんと計画・設計する。
    • ゴールの共有
  2. アジャイルなソフトウェア開発のためのマニフェストを読んだ後での「アジャイルとは何か?」
    • 協調して動く事
  3. アジャイルソフトウェアの12の原則を読んだあとでの「アジャイルとは何か?」
    • ヒューマンエラーを少なくする
    • 手作業を行わない
    • 会話---誤解を少なくする
    • 一定のペース
    • 開発プロセスに関する価値観の改革
    • 価値を高める、価値を濃縮する。
  4. IT用語辞典「アジャイル」を読んだあとでの「アジャイルとは何か?」
    • 誤解が多い開発手法
    • いろいろな解釈をされるもの
  5. アジャイルの押しつけを読んだあとでの「アジャイルとは何か?」
    • 哲学・思想・考え方
    • 型になれるまではそれに従う、その後は自分で発展させていく。

ライトニングトーク

C#のコードは初めてだけど、内容は分かった。VisualStudio2010のベータ版もらってきたので、試してみよう。実際の開発だとコードが先に書いてしまいがちなんだけど、それを予防するにはどうしたらいいんだろう。

現時点で日本国内では、アジャイルに対する誤解が少なからずある事、そしてその対処が必須であることを実感。そのために、お客さんや監査部門に対して「アジャイル」という言葉を使わない、なんて対策が必要になってしまっている業界の現状がとても残念。これまでのプロセスを定義して、マネージャが管理するっていうやり方の反対側にあるやり方なので、なかなか浸透しにくいのかも。

次は上司同伴のイベントがいいんじゃないかという話が出ていたけど、上司だけでなくお客さんも同伴して、アジャイルとは何か、アジャイルに対しての誤解を解く、アジャイルに対しての共通認識を作るみたいなイベントにしたらいいんじゃないだろうか。まずはアジャイルについて持っているイメージを列挙してもらって、みたいな。

懇親会

おもしろそうな話しているところに近づいて、こっそり会話している内容を聞いて回った。
名刺を作っておけば良かった。

懇親会が終わった後の片づけ

「机の移動を手伝っていただけませんか」というお願いで、残っていた参加者で適当に片づけを始める。

ゴールは会場の復元、床にある白い目印に机の位置を合せる。

という感じでみんな勝手に机やいすを移動し始める。うーん自律的だ。

今回のイベントから持ち帰ることができたもの

なんだろう。

  • 実際に仕事でアジャイル開発に取り組んでいる人たちがいると分かったこと。
  • セッション2の三井さんの事例が、受託開発でアジャイルをやるヒントになりそう。
  • 現段階ではアジャイルは誤解されることが多いので、その対策が必要になる。

くらいかなー。

MicrosoftのAgile Dayに行ってきた

皆様お疲れ様でした。

イベントレポートって何をかけばいいんだろ?
個人的な感想とふりかえりになります。また、勝手な解釈をしている部分が混じっている事を先にお詫びします。

見た感じ、スーツ率高い、参加している人はプロジェクトリーダ/マネージャが多いみたい。
また、実際に現場でアジャイル開発に取り組まれている方が多いような感じがしたけど、実際のところどうだったんだろう。

私の立場

セッションごとに印象に残ったこと

セッション1:アジリティを向上させるためにマイクロソフトが行ったこと〜Visual Studio 開発部門の場合〜

マイクロソフトでのアジャイルな取り組みについて。
大規模な製品開発(VisualStudioの開発)にアジャイルを取り入れた事例の紹介。
ちょっとまとめきれないので、印象に残ったところだけ書き出したけど、ヒントがいっぱい詰まっていそう。

  • VisualStudio2008の開発では新規開発を中断し、既存バグの根絶に集中した。
    • 標語は"Get Clean, Stay Clean"
    • ジョエルテスト#5「新しいコードを書くまえにバグを修正するか?」に通じる話。
  • リスク報告の正直さHonestlyが大事
    • 大雪のためスケジュールが遅延するなんて事まで書いてある。

TeamFoundationServerってどんなツールなんだろう。

セッション2:「開発現場でのムダ取り・改善活動」

アジャイルの成功事例をベースに、どういった改善活動をおこなったのかを紹介。

  • 時間が有言実行の障害になる。
    • 前に言った事でも、時間がたつと誤解されやすくなる。
  • ウォーターフォールは正解主義、アジャイルは適応主義。
  • 現時点で分かっている情報を元に仮説を立てる。
  • アジャイルでのマネージメントの役割は管理ではない、自律の手助け。
  • 数値はとってもいいけど、管理に使うな。
  • アーキテクチャ分析は最初にチーム全員でやる。
    • ゴールの共有、仕様の理解のため?
    • 「初めてのアジャイル開発」でも以下のように述べられている。

最新のIID手法では、開発構想書および「概要レベル要求のトップ10」一覧の作成や、負荷やユーザビリティや多言語化といったアーキテクチャに大きな影響を及ぼすような要因の分析を、早い段階でベースライン化するよう推奨している。

  • 問題が起こったとき、「お前なにやってんだよ!」ではなくて、「ちょっと教えてくれる?」で情報を引き出す。

セッション1で出ていたリスク報告の正直さを保つために必要な態度だろう。
たとえば、指先に熱いものが触れていて、それが脳に報告されなかったら、大やけどする。
神経が正直に情報を伝えるから反射的に手を引っ込めることが出来る。
リスクを見逃さないために正直さがプロジェクト必要なのかも。
怒れるマネージャはもらいが少ない。

セッションの内容ではないけど、懇親会の時に聞いた、受託開発でのアジャイル成功事例はおもしろかった。ドキュメンタリーとして読みたい。

  • アメリカのアジャイルは、自社内開発がメインなので、日本の受託開発にはそのまま適用できない部分がある。
  • プロダクトバックログの戦略的な選択。
    • およそ全体の4割程度のコアな機能を、顧客とのアーキテクチャレビュー時にデモンストレーションしたなど。

詳細設計書に何を書くべきか?

詳細設計書の書き方については黙っていられないので、ちょっと意見を言わせてもらう。

私も「詳しすぎる詳細設計書 - SiroKuro Page」で示されているようなコードと1対1に対応したような詳細設計書は、書くだけ無駄だと思っている。ただ、ちゃんとした詳細設計書をつくるなら、処理内容(内部の処理の実装方法)の書き方をどのように実装言語に合せるかではなく、処理内容を一切書かないようにするべきだと考えている。

なぜなら、処理内容をいくら詳細に記述したところで、それは仕様ではなくコードであり、仕様の代わりに記述したコードでは、バグも含めて記述されているため、そのコードのみでは正しいか間違っているかを判定できないからだ。
コードの他にどういった動作が正しいのかを判定する基準が必要で、その基準が仕様であり、詳細設計書にはその仕様を記述する必要があると考えている。

現に、例として示された処理概要では、出力の平均身長差を符号付きで返すのか、絶対値で返すのかが記述されていない、もし絶対値で返していたらそれはバグなんだろうか?仕様なんだろうか?処理概要では符号付きで返すみたいだけども、それは正しいのか?(重箱の隅をつつくようで申し訳ないが、バグをほじくり返すには重箱の隅をつついて、仕様を明らかにする必要があるのです。)

何も述べられていないと言うことは、「男性の平均身長」と「女性の平均身長」の差を符号付きで返したらバグなのか、仕様通りなのかも決められていないことになる。
だから、ある人がからすれば仕様通りでも、別のある人からすればバグになってしまう。
で、それがユニットテストでも判明せず(なんせ仕様として明記されてないので)、後の工程になってからバグとして顕在化する。

 例で示されている詳細設計では、処理の実装方法については述べられているが、以下の仕様に関して(特に異常な値の入力に関して)何も述べられていない。この辺が「実装するには物足りず、基本仕様としては詳しすぎる 」と言われる理由なのではないか?

  • nullが渡された場合どうなるか
  • サイズ0のリストが渡された場合どうなるか
  • 「男性の平均身長」と「女性の平均身長」の差は絶対値で返すのか、符号付きで返すのか?
  • 男性の人数が0だった場合はどうか?
  • 女性の人数が0だった場合はどうか?
  • リスト中にnullオブジェクトが入っていた場合は?*1
  • 何人程度まで考慮しなければいけないか?*2
  • 計算精度はどのくらい必要か?

では詳細設計書には処理内容の代わりに何を書いたらよいか?

処理内容を一切書かない代わりに書くべきなのは、詳細な仕様だ。それもテスト仕様書レベルのような本当にソフトウェアの仕様と密接に結びついた仕様が必要だ。

具体的には、TDDやBDDの考え方みたいに、どういう入力に対して、どういう結果になるかというブラックボックステスト的な振る舞いのみを記述する必要があると考えている。*3

参考:設計書の非常識1.設計書には詳細な実装方法を書く - Sacrificed & Exploited


この考えは
テスト仕様書に従ってテストをし、バグを管理するということは、
つまりバグかどうかの判断はテスト仕様書に基づいて行っているということであり、
ソフトウェアの仕様に最も近い表現をしているのはテスト仕様書なのではないか?
という思いつきをベースにしている。

これまでは、テスト仕様書に近いレベルの設計書を書く代わりに、詳細設計と称して処理の詳細=実装方法を記述してきた。そして、仕様は曖昧なままになった。
だからいくら詳細設計書をレビューしても、誤字脱字程度しか見つけられなかったのではないのか?
そして、曖昧なままの仕様に基づいて実装されたコードがユニットテストをすり抜け、結合テストシステムテストでバグとして顕在化してきたのではないか?
結合テストで出るバグのほとんどが仕様バグになってしまうのもこのせいではないか?(というのは言い過ぎか?)


また、このような単純なユニットテストレベルの仕様は別として、状態遷移やそのシステム独自の計算アルゴリズムといった、テスト仕様書だけでは説明しきれない、一段上のレベルの抽象的な動作を説明する設計書は別に必要だと思う。


実際に書き直したらどうなるのか

私が思いつく範囲で考えた仕様は次のとおり。

入力:
「性別と身長のペア」のリスト
出力:
男性の平均身長」と「女性の平均身長」の差
仕様

  • リストとしてnullが渡された場合、NullPointerExceptionを投げる
  • サイズ0のリストが渡された場合、0を返す
  • 返す値は、「男性の平均身長」と「女性の平均身長」の差を絶対値で返す。
  • 男性の人数が0だった場合は、女性の平均身長のみを返す。
  • 女性の人数が0だった場合は、男性の平均身長のみを返す。
  • リスト中に含まれるnullは計算から除外する。

とりあえずこれだけでも仕様として不定な部分は少なくなった。(と思う。計算精度が明記されていないけど。)
これだけでも十分だけど、テストパターンを追加するとしたら次のようになる。

  • 引数チェックなど
    • nullを渡したら、nullPointerExceptionを投げる
    • サイズ0のリストを渡したら0を返す
  • リスト内の男性と女性の組み合わせパターン(ちょっと冗長だけど。)
    • 片方が0人
      • 男性1人,女性0人
      • 男性2人,女性0人
      • 男性3人,女性0人
      • 男性0人,女性1人
      • 男性0人,女性2人
      • 男性0人,女性3人
    • 片方が最低1人
      • 男性1人,女性1人
      • 男性1人,女性2人
      • 男性1人,女性3人
      • 男性2人,女性1人
      • 男性2人,女性2人
      • 男性2人,女性3人
      • 男性3人,女性1人
      • 男性3人,女性2人
      • 男性3人,女性3人
  • リスト内にnullを含むパターン
    • リストがnullのみの場合、0を返す
    • nullと男性3人,女性3人の場合、nullが無視されて計算される。

あとは適当なテストデータを作ってテストすりゃあいい。
double型だと0.1という値は二進数では循環小数になって誤差が出るので、こういったことも考慮にいれて意地悪なテストデータを作るとなお良い。

*1:入力としてあり得ないなら例外を投げるべきだし、あり得るなら、その考慮をしたうえで処理をしなければいけない。

*2:最後の2つはシステム全体の設計に関わってくるので、基本設計で述べられている必要があり、詳細設計で記述する必要がないかもしれないけど

*3:内部の実装方法については一切触れないようにするというのは、javaのインターフェースの考え方に少し似ている。

システムのタイマーをラップしてテスト工数を削減する

システムのカレンダーやタイマーをロジック内から生のまま取得していると、テストの度にシステムのカレンダやタイマーを変更しないといけないため、やたらとテストが面倒になる。

たとえば、現在時刻を取得して稼働時間かどうかを判定する処理があったとする。システムのタイマーから現在時刻を取得して判定する事になるわけだが、この単体テストはどうなるだろう?

開発用クライアントPCでテストするのなら、割と簡単かもしれない。PCの時刻を変えて、テストして、テストが終わったら元に戻せばいい。しかし、サーバなどで簡単にシステムのタイマーをいじれない場合、どうやってテストすればいいだろう?

あるDBなんかは、システムのタイマーが巻き戻ると不具合を起こしたりする。DBに限らずタイマーの巻き戻りを考慮してないソフトなんかいくらでもある。こんな環境ではおいそれとシステムの時刻を変えるわけにはいかない。
仮にシステムの稼働時間の範囲が朝5時から夜11時までだったら、その時間まで待ってテストするわけ?
とってもめんどうだよね?


こういった場合、システムから直接日付やタイマーを取得するのではなく、間にテスト用に使う日付や時刻を返せるような仕組みを持ったラッパーメソッドを用意するとテストが簡単になる。

たとえば、起動時に特定のプロパティを指定すれば、その値を日付や時刻として返すようにラッパーメソッドを作っておくのだ。
そうすれば、いちいちマシンの日付を変えずにテストできる。
システムの時刻が変更できない環境でも深夜まで待たなくてすむ。

カレンダやタイマーに限らず、なんらかのロジックで分岐の条件として使う情報は、ロジック内で取得するのではなく、ロジックの外から渡してやった方がテストが楽になる。

DB接続だってロジックの外からテストDBにつながったDB接続を渡してやれば比較的楽にテストできるようになる。

このエントリではユニットテストの例を示したが、システムテストや受け入れテストでの扱いは
システム/受け入れテストで日付型と時間型をテストするが詳しい。


また、こういった、いかにテストしやすく作られているかをソフトウェアのテスト容易性といい、ソフトウェア品質特性ISO9126では保守性のうちの1つとして定義されている。ISO9126についてはオージス総研で公開されいているこの記事がわかりやすいと思う。

この例では比較的簡単なユニットテストレベルでの例を示したが、
先に示した記事の「2.1 機能要求と機能外要求」で、

実際のソフトウェア開発の現場では、機能要求と比較して機能外要求は識別しにくいということをよく耳にします。 その反面、ほとんどの機能外要求はソフトウェアアーキテクチャに影響します。 ソフトウェアアーキテクチャは、アプリケーションの設計全体に影響し、ソフトウェアアーキテクチャ設計にはエンジニアの高い技術力が求められます。 このことから、機能外要求の定義に漏れや誤りがあると、ソフトウェアアーキテクチャへの追加や変更に大きなコストや時間がかかることになります。 そのような事態を避けるためにも、機能外要求を網羅的に確認し、プロジェクトが見逃してしまった暗黙の要求としてしまわないことが重要です。

と述べられているように、システムのアーキテクチャレベルでいかにテストしやすく設計するかという事が大事です。
いざテスト工程になってメンテナンス用のハッチを取り付けようとしても遅いのです。

プログラマ35歳定年仮説について考えてみた

プログラマ35際定年仮説には、2つのとらえ方があって、1つは、表面的な仕事の内容と人月計算の利益が見合わなくなるため、プログラマの定年になるという話、もう1つは、技術に追いつけなくなって、やっぱり定年になるという話。このエントリでは後者の技術的に追いつけなくなる場合について述べる。

かなり乱暴なたとえだし、ソフトウェア開発は製造ではなく設計や研究開発に近い性質を持っているというのを承知したうえで言うが、ソフトウェア開発業におけるプログラマは、半導体製造における製造装置のようなものではないか。
というのは、定期的に投資して更新していかないと市場の要求を満たさないレベルの設備しかもてず、仕事が先細りになっていく部分が似ているのではないかと考えたからだ。

プログラマに対しての投資というのは、新規の要素技術やフレームワークなどを実際に使わせてみて、その技術についてのノウハウを少しでもいいから蓄積することに当たるのではないか?
そうすることで新規技術を使った案件を獲得しやすくなったり、開発が効率化できたりする。

これまでの日本のIT企業でのプログラマの扱いを振り返ってみると、プログラマに対しては実務が最優先されるあまり、こういった新規技術に触れる機会を個人の努力に頼ってきたように思う。いや、それどころか、残業につぐ残業で個人の自由時間さえも奪ってきた。

その結果としてプログラマが35歳あたりで使い物にならなくなってしまったのではないか?まあ、人月計算によるところがだいぶ大きいとは思うが。

googleのような20%ルールとはいわないまでも、プロジェクトの合間にこれから伸びそうな分野の技術について学べる時間を用意するのが企業側の努めではないだろうか?


余談だが、社内で専門の教育部署をもっているほど大きな会社であっても、プロジェクトの方が優先されて、結局教育というか人への投資があとまわしになってた事を思い出した。
講座は予約制で、プロジェクトのトラブルなどで講座を予約した当人の都合が付かないと、同じ課内の別の人間が受講しないか聞いて回ってた。ほんとおかしな話。

また、講座を「お勉強」といってバカにしていたというのも思い出した。たしかに講座の内容は物足りなかったけど、社員への教育に力を入れているように見えて、形式だけだったという会社もあるんだね。