|
|||
はじめに | |||
みなさん,こんにちはー(音声は変えてあります)! 今日は,私たち二人で挑戦してみた「プチXP」の体験談をお話したいと思います. XP(エックスピー)は,eXtreme Programming(エクストリーム・プログラミング) の略で,Kent Beck らによって提唱されているまったく新しいソフトウェアの 開発方法論です.まだ読まれていないかたは, 『XP エクストリーム・プログラミング入門』, 『XP エクストリーム・プログラミング導入編』などの書籍を読むか, あるいは,この記事の最後に紹介する Web ページを参照してください. いま,XP関係の本や記事があちこちに出るようになってきていますが, 「ほんとうにうまくいくの?」とか「うちの会社じゃ無理だよね」なんて声も 聞こえます. 私たち二人も,XPに興味はあるのですが,なかなか実際には やってみることができませんでした.今回,マネジャの理解もあって 「とにかくやってみよう!」と気楽に始めたのが,この「プチXP」です. XP のプラクティスの中には,すぐに始めるのが難しいものもあります. 例えば,顧客をプロジェクトに一人よんでくる「オンサイト顧客」 なんかは,日本ではなかなか難しいかもしれませんし,残業を しない,という「週40時間」というのも現実にはきびしいでしょう. そこで,今回は「できることを,できる範囲でやる」という心構え でこの体験にのぞんでいます. 3週間の実践を終えて,ようやく形あるものになりましたので,報告も兼ねて この記事を書くことになりました.今XPを猛勉強中の私たちですが, かざらない「なま」の声,「なま」の現場をレポートしたいと思います. どうぞよろしく! |
プロジェクトのかたち | |||||||||
少しこのプロジェクト概要について説明したいと思います. プロジェクト名前は,SSS (エス・エス・エス). 「Simple Schedule Service」(シンプル・スケジュール・サービス)の略です. 私たちの会社では,「Webサービス同好会」というサイト ( http://objectclub.esm.co.jp/webservice/ml.html )を立ち上げていて, そこで,今はやりの「Webサービス」の実験を行っています.そのサ イト向けに,簡単なサービスを実装しよう,というプロジェクトです. 開発期間は3週間でワンリリースです.実験的に行ったプロジェクト なので,一回リリースして終りということになりました.XP では プロジェクトを「リリース」に分解し,さらにリリースを「イテレーション」 に分解します.今回, イテレーションは1週間をベースに考えましたが,長さは変則的です. つまり,イテレーションに入力するストーリーの数や大きさで, 1イテレーションの長さを変えています.
SSS は,言って見れば簡単なリマインダー(備忘録)サービスで,自分の スケジュール(内容,日時,通知先)を登録しておくと,その予定をメールで 知らせてくれる,というものです. 今回は,Webサービスの勉強も兼ねてこのプロジェクトをスタートさせました. Web サービスも XP もはじめての体験です.さて,うまくいくでしょうか? |
使った技術など | ||||||||||||
基本的な環境として,以下のものを使いました.
開発環境
見て頂ければわかるとおり,ほとんどがオープンソースのツール群で 構成されています.XP みたいにフットワークの軽い手法には,やっぱり オープンソースがぴったりくるみたいです.試してみる,っていうときに お金がかかるものは手が出しにくいですよね.それに,最近はオープンソース の方がWeb上の「お助けドキュメント」が充実しています.困ったときも検索サイトで キーワード検索すれば,たいていは解決します. また,今回はせっかくのWebサービスなので,メールの送信に関しては 外部の Web サービスを利用することにしました. 開発は,自分たちのパソコンからネット上の Linux マシンにログイン して行っています.Windows のデスクトップになれた私たちには 最初ちょっともどかしかったのですが,使うコマンドも限られていたので すぐになれちゃいました.コマンドラインからの操作は,GUI にはない サクサク感があって,慣れると快適でした. |
エックスピー! | |||||||||||||
XP には,「12のプラクティス」といわれる実践項目があります(コラム参照). 極端に言えば「この12個さえ守れば開発はうまく行く!」という ありがたい教義なのですが,実際の開発現場では,なかなかすべてを実践する 分けには行かないでしょう.もともと,XPに限らず開発プロセス, 開発方法論というものは,現場にフィットしなければ意味をなさない ものです.XP自身も,実際はもっと柔軟に考えられており,組織に応じて プロセスをカスタマイズすることがある程度前提となっています. 今回は,XPのプラクティスのうち, 厳選したものしか取り入れていません.できるものだけやる,という 気ままなスタンスでXPに取り組んでいます. 次のリストが,実際に採用したプラクティスです.
この中には,Kent Beckの「12のプラクティス」に書かれてないものが あることに気付きましたか? これらは,
です.では,実際に上のプラクティスを簡単に説明し,私たちがどのように 実践したかを紹介していきましょう. 計画ゲームこれは,全員で行う計画づくりのミーティングです. イテレーションの最初に,ゲーム形式のプランニングを行います. 本当は,顧客も入ってチーム全体で行うミーティングですが, 今回は顧客なし. マネジャが仕様の権限をもっているとみなして,顧客のかわり をしてもらいました.ストーリーカードにやりたいことを書いてもらい, それを私たちで見積もります.それを見て,マネジャが優先順位を決める という流れで進みました. 本来は,計画ゲームは「リリース計画」と「イテレーション計画」に 分かれます.リリース計画で,1回のリリース分の計画を立てます. リリースは,何回かのイテレーションに分割されます.そのイテレーション 毎にイテレーション計画があります. 今回は,1リリースだけの開発で期間も短いため,簡略した方法で行いました. まず,とにかく最終的にやりたいことを全部カードに書き,それを見積もる. そして,優先順位をつけて1イテレーション分だけの計画を立てる, という方法を取っています.あとで実況中継をしたいと思います. スタンドアップミーティングこれは,毎朝の全員参加ミーティングです.私たちのチームは机を向かい合わせた 「島」で仕事をしていたので,朝,9:30 にみんなが立ち上がって簡単な 会議をしました.これは,XPの本にはプラクティスとして位置付けられて いません.でも,私たちにはとても重要なものに思えたので,あえて, プラクティスとして取り上げています. スタンドアップミーティングでの会話は,
が主です.今回は,ペアは固定だったのでペアリングの時間は とりませんでした.通常は,タスクを持っている人が「誰さん, お願い」っていう風に声をかけます.もし特定の分野に強い人 が分かっていれば,その人をコーチが推薦することもあります. スタンドアップミーティングは,15分以上の時間をかけないことが肝心です. チームによっては,キッチンタイマーをかけるところもあるそうです.細かい 話になりそうなら,司会者は「それについては誰と誰で後で話そう」などと話 を区切らないと行けません.それから,いちばん大事なのは,問題が起きた場 合に犯人探しをしないことです.原因を見つけることは重要ですが,その対処 に焦点をあてて話ましょう. メタファこれは,システムを一言で表す比喩です.ちょっと難しいプラクティス ですが,今回やってみました.XPをやるときによく問題になる, 「悪名高き」プラクティスです.日本でうまくやっているのを聞いた ことがありません. よく例にだされるのが,SETI@HOME プロジェクトの「蜂の巣」 メタファーです.このプロジェクトは,宇宙線(?)のデータを 解析して地球外生物の存在を探る,というもの. インターネットに継ったコンピュータのCPUの空きを うまく使って,膨大な計算を分担して行い,結果を収集します. この様子は,ちょうど蜂が密を求めてさまよい,密が見つかると それを持って巣に帰って来るのに似ていますよね.ですので, 「蜂の巣」メタファーは直感的にぴったりきます. メタファーによって, 顧客と機能の会話がスムーズに行ったり,将来の機能拡張を考えたりできます. もう1つの重要な点は,システムの中に出て来る名前(クラス名やメソッド名) に一貫性がでることです.開発者間のコミュニケーションがスムーズになり, コードの共同所有やペアプログラミングを支援します. 今回「ホテルのモーニングコール」というメタファーを作って見ました. ですが,イメージは共有できたものの,内部のオブジェクトに関する 命名やおおまかな動作についてはほとんど訳に立っていません.そこで, メタファーの第2の役割を補強する目的で,「用語辞書」というプラクティス を入れることにしました.あとで計画ゲームの実況中継に,メタファー が出てきます. ミッションステートメントこれも,オリジナルのプラクティスです.目的は,プロジェクトの中で 実際のシステム構築以外に自分なりの目標をもつ,ということです. 例えば,「今回はWebサービスを自分のものにするぞ!」とか,そんな 意気込みです.このプラクティスは,マネジャが新しく提案したものです. どうも,XPで行うこのプロジェクトが「お遊び」にならないか,気に したようです.これによって,目標をもってこのプロジェクトに 参加することを期待していました. 受け入れテスト顧客が受け入れのためのテストを書きます.これは,マネジャにお願いしましょう. このテストも JUnit で行いました.作るものが Webサービスですので, ツールで自動生成されるクライアント側のプロキシを使えば JUnit でも簡単にテストができます.Web サービスって便利!って思いました. スパイクアーキテクチャこれは,XPの本にはプラクティスとして位置付けられていません. 計画ゲームの中に含まれるのかもしれませんが, XPの開発では実際によく行われているようです.開発に 入る前に,簡単なアーキテクチャの「種」にあたるものを作って しまうのです.ガチガチの完成したアーキテクチャではなく, シンプルでおおまかな構造をある程度決めてしまいます. これによって,スタートが切りやすくなります.何もないところから, さあはじめよう,って言っても難しいですからね. テストファーストこれは,開発者から見た,「XPの真髄」にあたる部分でしょう.
という作業の繰り返しによってコードを書いて行くものです. JUnit によるテスティングが必須です. 今回は,これを徹底的に行いました.やってみると結構難しいのですが, グリーンバー(JUnit の成功)は快感です.もう「やみつき」って感じです. ペアプログラミング二人ペアでプログラミングするもので,略して「ペアプロ」です. でも,私たちは二人しかいないの で,同じペアでずっとプログラミングすることになりました.でも, ときどき,マネジャやコーチにも,臨時でペアになってもらうことも ありました.テストも コーディングも設計もリファクタリングも,ずっとペアでやっています.この プラクティスは,「書いているそばからレビューをしている」 と考えることもできます.でも,役割はその都度交代しています. キーボードを使って実際にコードを打ち込む人を「ドライバー」, 見ている人を「パートナー」と呼びます.「パートナー」は 名前やスペルのチェックをしたり,次のテストを考えたり, 全体との整合性を考えたりします. ペアプログラミングをうまくやるには,ある程度の「心得」が必要です. この心得を10箇条として書きました.
コードの共同所有チーム全員でコードを共有します.といっても二人なので,問題は ありません.だた今回,CVS(Concurrent Versions System)を積極的に 導入して使ってみることにしました.二人ともちょっとさわった ことはあるのですが,本格的に使うのははじめてです.CVS は, RCS(Revision Control System) の後継にあたります (実は内部でRCSを使いる).RCS に比べて CVSの良い点は,
というところです.編集が運悪くぶつかってしまったときは, マージすることになります.とはいっても,今回はペアが1つだけ なので,実際にぶつかることはありませんでしたけど. 今回は,リファクタリングなどを行う過程で,失敗したら一つ前の バージョンにすぐにもどれる,という点で CVS を活用しています. これはとても重要だ,と思いました. 「ペアプログラミング」と「コードの共同所有」, それに「スタンドアップミーティング」によって,チームの 仲間意識が大幅にアップします.この3つのプラクティス が,コミュニケーションという意味では XP の核になっている のでしょうね. リファクタリングこれは,もうお馴染みですね.動いているコードをきれいにクリーニング するというものです.機能を変化させずに内部を整えるのがポイントです. それに,テストがちゃんと備わっていて,動いていることが必要になります. 勝手に触って壊してしまってはいけませんし,テストなしでは恐くて触れません. 今回,特にちゃんと「リファクタリングの時間」を取ったこともポイントです. ある程度できたと思ったら,ちゃんとリファクタリングして,シンプルで かっこいい(自分が納得できる)コードに直すのです. 主なリファクタリングは,「コードから重複を取る」ことです.3行以上の 連続したコードパターンが現れたら,メソッドとして抜きだす,というのが 黄金のパターンです.また, リファクタリングには,「名前の変更」も含まれます.ちょっと変な名前 だなぁ,と思ったら辞書を引いていい単語を探します.いい単語は, 「用語辞書」に加えます.同じ用語が一貫してコードに現れるようにします. 今回は,リファクタリングにコーチも入ってもらいました. コーチのアドバイスを受けながら,1ステップずつ変更しました. もちろん,その都度テストを全部通します.1ステップ通ったところで, ちゃんと CVS にコミットすることも大事.失敗しても,最悪前のコードに もどることができます. シンプルデザインシンプルに設計する,って言われても・・・・とても難しいです. 今回は,「タスクを満たす,いちばんの近道をする」と解釈しました. どうせこの機能も後から必要になる,と思って今追加してはいけません. 今のイテレーション だけを視野に入れて設計をします.設計が近視眼的になって, 後からうまく変更が入らなくなってしまったら どうするのかって? それはそのときに直すんです.そのための, リファクタリングなんですから.それに,予定されていた機能が, 顧客の都合でやっぱりやめ,ってこともありますし.そのために, イテレーション毎に計画ゲームをやるんですから. コーディング標準コーディング標準は,チームに1つソースコードの標準的なフォーマット を決めるというものです.ペアプログラミングをしながら,ソースコード のインデントやカッコの付け方などで無用の議論をしたくはないですよね. 今回のプロジェクトでは,これはやったような, やらなかったようなプラクティスです. というのも,1年以上チームを組んでいると,コードフォーマット はある程度固まってくるものですよね.ですから,特にこれ, と決めはしませんでしたが,「いつものように」コーディングしました. 用語辞書これは,オリジナルのプラクティスの中でもマネジャがいちばんお気に入り のものです.よく,「メタファ」は難しいと言われます.メタファには,
という役割があります.特に,2 では,「名前の体系」(System of Names) を持つことが重要になります.メタファーはこの「名前の体系」を形成 することを助ける働きがあります.ですが,特に日本では,英語と日本語 の問題があります.普段の会話は日本語で行われますが,コーディング に現れる単語は,英語の方が多いようです.例えば,「予定を追加する」 というメソッドは,「addSchedule」という風になります.日々の会話の中で 「予定」と呼んでいたものが,Schudule なのか,Appointment なのか, 追加が add なのか insert なのか.システム全体で単語の 使い方がばらばらだったら,とても混乱するでしょう.ペアプロや リファクタリングの大きな障害になりそうです. このプラクティスでは,「用語辞書」というものを最初のイテレーション で作り,一貫してそれを見ながら名前を付けるというものです. イテレーションが進むにつれて,この用語辞書は成長していきます. 用語辞書は,「用語」「英語訳」「意味」の3つを対にして書いて行きます. 例えばこんな感じです.
|
登場人物紹介 |
では,実際の開発の様子を実況中継でお伝えしたいと思いますが,その前に,登場人物の紹介です. MT - 田中 真弓プログラミング歴4年. データベースを使った業務系のサーバーサイドJavaが得意. 最近,部署がえがありマネジャのチームに参加. ST - 飛山 祥子プログラミング歴2年.入社してすぐにリアルタイム系 の C++ をやってめまいを覚える.今はやっぱりサーバーサイド Java です. KH - マネジャ二人の上司にあたる.プログラミング歴15年. 今回は「マネジャ」,「コーチ」,「トラッカ」の役割として このプロジェクトに参加.プロジェクトを見守る役目. YO - お助けマン二人の先輩にあたる.プログラミング歴8年. Web 系の開発ならなんでもこい.最近 Web サービスにのめり込み, 「Webサービス同好会」なるサイトを立ち上げている. UNIX や Java にも精通している.今回は,「コーチ」でもあり 困ったときのたのみの綱として参加. 基本的には,MT と ST でプロジェクトを進めます.ミーティングには マネジャのKH も参加します.ときどき,YO も顔をだすことになると思います. |
計画ゲーム | |||||||||
計画ゲームの例として,一番最初のミーティングを実況中継しましょう. はじまり -- ミッションステートメントKH: じゃあ,はじめましょう.お菓子持って来たから食べながらやろうね (PRINGLES を配る). まず,このプロジェクト「Simple Schedule Service」 (シンプル・スケジュール・サービス)の概要は, この前話した通りです.スケジュールを入力しておくと,それを メールで知らせてくれる Web サービスです.今からは,SSS(エス・エス・エス) と呼ぶようにしましょう. 最終的に「Webサービス同好会」のコンテンツとして出したいので, はりきって行きましょう. KH: で,ミッションステートメントは書いてきた? ST: はい.こんな感じでいいですか?
うん,グッドだね.今回の DB は Postgres だね.Linux も 初めてだっけ? 前に UNIX は少し触っているから大丈夫だと思うよ. MT: 私はこんな感じです.
KH: はい.いいですね.たぶん,UML はホワイトボードに書く ことになると思うけど,あまり UML の文法には拘らなくていいから. 構造と動きをおおまかに理解するのに使おう. 今回は XP も Web サービスも始めてだから分からないことはすぐ 相談してください. MT, ST: はーい. KH: それと,Linux や Web サービスで分からなくなったら,YO君 にヘルプしてもらおうね. ストーリーを書くKH: じゃあ,ストーリーを書こう.いちおうぼくが顧客を 兼務するから,まずは適当に書いて見るね.
KH: すごく簡単だけど,こんなんでどうかな.今回,折角 Web サービス なんだから,外部の使える Web サービスは利用しちゃおう.つまり, メールの送信自体は,別の Web サービスに依頼する形にしよう. XMETHODS(http://www.xmethods.com)というサイトに,現在公開されている SOAP, WSDL ベースの Web サービス一覧があるよ.そこで使えそうなのを 調べておいてね. ユースケースを書くとこんな風になる.
ストーリーを見積もるKH: じゃあ,見積だ. 見積は,「自分が専念したら何日でできるか」という値を出すんだよ. これを「ポイント」という単位で呼んだりする.チームによっては, 適当な単位を付けているとこもあるんだ.ぼくが聞いたチーム では,「アフロ犬」なんて単位を使ってたな. でも,今回は単純に「理想日」で見積もろう.じゃあ, 見積もってみて. MT: 最初は,環境とかの設定で時間がかかりそう・・. まず,「(1)予定を入力する」ですけど,4理想日くらいかな. ST: そうですね.そのくらいは見ておいた方いいかな. Web サービスやったことのある人に聞いて見よう. (YO さんに聞きに行く...) ST: 3日あればでできるそうですよ.ですけど,最初だし多めに みて4理想日にしよう.データベースの設定とかもあるしね. KH: 分かった.でも,最初のイテレーションは一週間,つまり5日 しかないよね.最初のイテレーションでゴールデンパス,つまり いちばん重要な機能をひとまわり通したいと思っているんだ. 二人で5日なので,10日の持ち点があるんだけど, 負荷係数を2で見積もっても5理想日分しか最初のイテレーションで できないことになる.
だから,もし「予定を入力する」ストーリだけで4理想日とすると, これだけでほぼ持ち点を使いきってしまうね.... MT: じゃあ,ストーリーを分解しましょうか. ゴールデンパスは,たぶん予定を入れて,通知がくることだから, 予定入力のオプション的な機能は別のストーリーにしたらどうでしょう. KH: そうだね.じゃあ,こう書き直そう.
KH: 了解.じゃあ,ゴールデンパスとして,1, 2, 3 を入れよう. これで,5理想日になる. ST: ちょうどうまく行きましたね. KH: 拍手! ST, MT: パチパチ. スパイクアーキテクチャKH: じゃあ,ここから,最初のイテレーションに集中して,タスクを 出していくことになるんだけど,その前に,ソフトウェアの 全体の構造はどういう風になるのかな? 最初のイテレーションのストーリーは,3つだ.
これを実現するための絵を描いて見ようよ.MT さん描いてみて.
うん,だいたいそんな感じ.ちょっとDBが大きいね.DBを扱ったことの ある人は,「DBありき」で考えてしまう場合が多いんだ.もう少し役割を 分割して,クラスのレベルにまでブレークダウンしよう.UMLっぽく 書いて見ようか. (全員でホワイトボードで議論しながら,このような絵がかけた)
Webサービスの口は,「SSSコントローラ」と名付けよう. これが,内部のデータ管理である「モデル」に「スケジュール」 を登録する.この流れとは別に,「タイマー」を持った「監視」 がいて,定期的に「モデル」を参照して,通知が必要であれば 「通知」に依頼してメールを送ってもらう.モデルは,実際にはDB を用いて実装することになるだろうね.それも書いておこう. それぞれの日本語に対応する英語も 書いておこう.実際にコーディングするときは,この英語にそろえよう. ST さん,用語辞書に登録しておいてね. KH: じゃあ,ついでにメタファーも決めよう.何かいいアイディアはない? YO: あらかじめ指定しておいた時間に届けてくれるんですよね, だから,「宅配便の期日指定」っていうのは? MT: うん,いい感じですね.全体の動きはうまくあらわされていると思う. ST: 「モーニングコール」っていうのはどうですか? ホテルで翌朝,電話 で起こしてくれる. KH: うん,きれい,きれい.たぶん,モーニングコールのシステムって こんな感じになってるんだろうね.キャンセルもできるしね. YO: これは美しいメタファーだな.これで行こう. KH: 良い気分だし,休憩しよう. タスクの書き出しKH: では,とりあえず,最初のイテレーションに集中して,タスクを 出して見よう.どんな作業があるだろう. MT: データベースもあるし,CVS もいるし,Linux にユーザを作らないと. KH: うん,最初はインフラの整備がいろいろあるね. じゃあ,タスクを書き出してみようか.何をやらないと行けない? MT: データベースの設定とかもタスクに入れるんですか? KH: うん.やることはすべて出してみよう. ST: データベース,CVS .... (ホワイトボードに書き出す) MT: で,実際に作るクラスは,Model, Schedule, Watcher,....(ホワイトボードに書き出す) KH: Model(モデル)と Schedule(スケジュール), それから, Watcher(監視) と Notifier(通知) はそれぞれ 1まとめのタスクにした方が分かりやすいね.
KH: こんなもんかな.じゃあ,タスク毎に見積もろう. 自分がやりたいタスクにサインして,見積を書いて. MT: サインって言っても,二人しかいなくてペアプロだったら, 結局全部やることになるのでは ? KH: うん.そうなんだけど,タスクの完了に責任を持つ人を 決めたいんだ.それと,後で見積の精度をトラッキングしたいから, サインした人,つまり見積した人が誰かを記録したい意味もある. ST: じゃあ,私,今回ミッションステートメントで「DB に強くなる」 って言っているので,データベース設定やります.MTさん,手伝ってくださいね. (ここで,UNIXに強いYO君登場) YO: お,XPやってるね. KH: いいとこに来たね.Linux マシン使いたいんだけどさ, mild って名前のマシンつかってもいいかな? YO: ええ,あれは開発用だから自由に使っていいですよ.ユーザ設定 とか,やりましょうか? 全員: おおー,是非,是非. YO: じゃあ,環境の設定まわりはぼくがやります.0.5 日で終ります. .... っとこんな感じでミーティングが進み,タスク表ができあがりました. 一週間は5日ですが,負荷係数を2として,一人2.5日を目安にタスクに コミットしています.YO 君は一時的なリリーフです.
これだと,全員の合計が6日になります.本当は1日分オーバーなのですが,YO 君が入ってくれたのと,まあ,最初なのでとりあえずこれで始めて みよう,ということになりました. ホワイトボードに書かれたタスクは,模造紙に書かれて壁に張り出されます. そして,終了したタスクから,横線を引いて消します.消したら,完了日と 実際にかかった日数を書き込むようにしました.これで,どのタスクが 見積より難しかったか,あるいは見積よりも簡単だったかが分かります. 例えば,第1イテレーションが終ったあとのタスクの模造紙は,こんな感じ になりました.
|
テストファースト! | ||
さて,実際にペアプログラミングでテストファースト, リファクタリングを行っている様子を紹介します.ペアプロの現場の写真 もお見せしましょう.二人の後ろには,そのイテレーションのタスク を書いた模造紙がはってあります.そして,ストーリーカードは 「終了」と「TODO」に分けてはりだされているのにも注目してください. ペアプロ中の MT と ST
ユニットテストの実際まずは,ユニットテストを使ったテストファースト開発です.
~ ストーリ ~ ST: このタスクのテストから書きましょうか.テストメソッド名は何にしましょう? MT: 予定の追加を確認だからtestAddScheduleでどう? ST: こんなかんじでいいですか? Schedule は 予定の入力者,予定日,内容, 予定の通知先を持ったクラスで,コンストラクタで全部設定できるように します. |
public void testAddSchedule() throws SSSException { Schedule sc = new Schedule("test@esm.co.jp", "2002/03/31 15:00", "出張", "test@esm.co.jp"); SSSController.addSchedule(sc); } |
ST: あっ,これをどうやって確認しましょう.. MT: DB に登録して,それを確認することにして,今はとりあえずコンパイルしよう. ST: あー,コンパイルエラーだ.メソッドないですもんね.あたりまえか. MT: じゃあ,addSchedule を実装しよう! DB への接続は別のメソッドにしますね. getDB という private メソッドを作ってっと.SQL 文はこれで合ってます?
MT: これでどうかな.コンパイル・・・. ST: 通りましたね.それじゃ,テスト.
ST: すごーい,とおりましたね!!ちゃんと通ったテストにチェック が付くんですね. MT: add しただけで,何も assert してないから当然だよね. MT: DB にちゃんと追加されてるか,確認しよう.psql(PostgreSQLのシェル) で直接確認っと. ST: あー,ちゃんと追加されてますね.でもこれってテストとしてどうなんでしょう.. MT: そうだねえ.テストメソッドの中でちゃんとテストしないとね. それじゃgetメソッドを作ろっか.とりあえず get を作るタスクはないんだけど, これがないとテストできないもんね.じゃあこっちのストーリーに移ろう!
~ ストーリ ~ ST: まず最初は,何も登録されてない場合のテストを書きましょう. MT: それじゃ,こんな感じでどうかな?
MT: じゃぁ,コンパイルっと.はい.約束通りコンパイルエラー. ST: メソッド作りましょう.
MT: コンパイル通った.じゃあ,実行!
ST, MT: わーい.成功した~.testGetEmpty が,通ったテストに追加 されてますね. ST: 今は null が返ってきて当たり前ですね.じゃあ Schedule が返ってくるテストを書きましょう. MT: さっきの中途半端だった testAddSchedule に付け加えればいいんじゃない? 追加した Schedule を,問い合わせで取って来ればいいんだよね. |
public void testAddSchedule() throws SSSException { Schedule sc = new Schedule("test@esm.co.jp", "2002/03/31 15:00", "出張", "test@esm.co.jp"); SSSController.addSchedule(sc); Schedule[] scs = SSSController.getSchedules("test@esm.co.jp"); assertEquals(1, scs.length); assertTrue(scs[0].equals(sc)); assertTrue(scs[0].getNeedNotify()); |
ST: コンパイルエラーになりましたね.じゃあ実装.DB からスケジュールを とってくる部分は,private メソッドにして括り出しますね.
MT: コンパイルとおったね.じゃあテスト実行. ST: 通りましたね♪ MT: 日付が不正だったらどうするんだろう. ST: 顧客役に聞いて来よう.(ストーリーカードを持って聞きに行く) KH: うーん,どうしようかな...例外出してもらおうかな. ST: わかりました.SSSException でいいですか? KH: うん.とりあえずそれでいいよ. MT: じゃあ,不正ななデータを add する場合のテストもしよう. ST: そうですね.そんじゃメソッド名は testAddBadDate でどうでしょう. 日付のフォーマットは,"yyyy/mm/dd hh:mm" でしたよね."1111" なんてヘンな 文字列入れますね. この場合,SSSException 例外が帰って来るのをテストするんですよね. 例外はどうやってテストするのかな... MT: catch の方に assertTrue を入れて,そこを通っていることを確認しましょう. それと,念の為に addSchedule の後のコードが実行されていないことも, fail を入れておいて確認っと.さらに,Exception 全体も catch して おいて,他の例外でないことも見ておきましょうか.
MT: コンパイルして実行っと.
ST: テスト失敗しちゃいましたね.あ,当たり前か.実際に不正日付の チェックしてないですもんね. MT: だめだったテストメソッドには, ばってん(×)が付いて表示されるんですね. ST: チェックするロジックを書きましょう. チェックはどうやってやるのかな.... MT: たしか,java.util.text パッケージに日付のフォーマットとパース のためのクラスがあったはず.API を調べてみよう. ST: ありましたね.SimpleDateFormat ですね.ふむふむ,parse に失敗 すると,ParseException ですね.これを捕まえましょう. MT: うん.DB の属性を not null にしてるけど, 不正日付のチェックを入れるなら null チェックも入れようか. null の場合も SSSException 投げるようにしましょう. できるだけ,細かいお助けメソッドを作って重複をさけましょう. |
public void addSchedule(Schedule sc) throws SSSException { Connection con = getDB(); // beginTransaction String owner = sc.getOwner(); String date = sc.getDate(); String content = sc.getContent(); String notifyee = sc.getNotifyee(); if(stringIsNull(owner) || stringIsNull(date) || stringIsNull(content) || stringIsNull(notifyee)) { throw new SSSException("NullPointerException addSchedule.owner = " + "'"+owner +"'"); } try { java.util.Date d = parseDate(date); String sql = "insert into schedule values (nextval('schedule_id')"; sql += ",'" + owner + "','" + DATE_FORMAT.format(d); sql += "','" + content + "','" + notifyee; sql += "')"; Statement stmt = con.createStatement(); stmt.executeUpdate(sql); con.close(); // endTransaction } catch(Exception e) { throw new SSSException(e.getMessage()); } } private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm"); private static java.util.Date parseDate(String dateString) throws java.text.ParseException { return DATE_FORMAT.parse(dateString); } private static boolean stringIsNull(String s) { return (s == null || s.trim().equals("")); } |
MT: コンパイルして実行! ST: オッケーですね. リファクタリング第2イテレーションに入って,modifySchedule,removeSchedule を 作成しようとしたときに,addScheduleと重複するロジックが存在すること に気が付きました.
MT: 赤字の部分が重複するところだよね. ST: それじゃ,null チェックと dateチェックのところを括りだしましょう.私書きますね.
MT: だいぶすっきりしたね. あとは残った赤字を括りだせばOKかな?メソッド名 execute で括り出そうか.
ST: すごいすっきりしましたね.いい感じ♪ modifySchedule はこうなりますね.
MT: そうだね.これでテストを通してっと. やった!通った!!ユニットテストを使うとリファクタリング後の デグレードもきちんとテストできていいね. 開発は,終始,こんな具合に進みました.DB がからんだテストでは, JUnit の setUp() メソッドをうまく使ってDBをクリアして, 各テストが混ざり合わないように工夫をしました. |
クライアント | ||||||||||
第2イテレーションまでで,サーバー側(Webサービス)は完成しました. 一応,これで作業は完了なのですが,やっぱりクライアントも作って みたいですよね.今回は,第3イテレーションで, 3月末発売のVisual Studio .NET(製品版) を使って,GUI をもつアプリケーションを作ってみました. Web サービスを実際に呼び出しています.クライアントの GUI を 紹介しましょう.Visual Studio が提供している GUI コンポーネント をふんだんに使っています. ここで,クライアントの画面と使い方の簡単な紹介だけしておきましょう. このクライアントは,ソースコードを公開しています.後の「公開」の 章を見て下さい. 起動とログインSSSClient.exe を起動すると以下の画面が立ち上がります.
『ログイン』ボタンを押すと,ログイン画面が表示されます. 予定入力者のメールアドレスを入力すると,ログイン完了です. このメールアドレスが,通知メールの差出人になります.
カレンダー表示ログイン画面で入力したメールアドレスで登録されている予定日付が太字で表示されます. 太字の日付を選択すると,その日付の予定一覧がリストに表示されます. 予定を入力したい日付を選択して,『スケジュールの設定』ボタンを押して 次へ進みます.
予定の追加/変更/削除図の画面が表示されます.必要な項目を入力します. 変更,削除の場合は,リストから予定を選択して処理を行ってください. 以下は入力データの説明です.
|
公開 | ||||||||||||
この Web サービスは,クライアントの参照ソースとともに「Webサービス同好会」 で公開しています.
http://objectclub.esm.co.jp/webservice/ml.html 公開の仕様は,次のようなものです. シンプルスケジュールサービス
予定を入力するとメールで通知してくれるサービスです.
|
反省と感想 |
さて,こんな風に私たちの開発は進み,3イテレーションでうまく公開 へとこぎ着けました.今回の「プチXP」開発を反省してみましょう. ミッションステートメントまずは,個人のミッションステートメントは達成されたでしょうか? MT さん
ST さん
二人とも,それなりの成果は出たようです.大切なのは,あとで 達成できたかを反省することではなく,ミッションを持っての開発にのぞむと, タスクへのコミットが意識的にできる,という部分だと感じました. では,それぞれのプラクティスに関して二人の感想をまとめてみました. 計画ゲーム
スタンドアップミーティング
メタファ
受け入れテスト
スパイクアーキテクチャ
テストファースト
ペアプログラミング
コードの共同所有
リファクタリング
シンプルデザイン
コーディング標準
用語辞書
|
まとめ |
さて,私たちの XP 体験談はどうでしたか? 最後に,私たちが今回感じたなかで, XPについて期待していることを書きたいと思います. 今までの開発手法では,システムを作って行くときに必ず 担当をしっかり分担して行きます.でもこのやり方だと, システムのある部分を知っている人が限られてきて, その人が抜けるとどうにもならない,という場面が起こります. 「あ,そこは誰だれに聞かないと分からない」という状況です.
XPを使えば,特に,「ペアプログラミング」,「コードの共同所有」 それに「スタンドアップミーティング」をやりながらシステムを 作って行くと,システム全体の知識がチーム全体にゆるやかに 蓄積されて行くのが分かります.ですから,一人抜けたとしても チーム全体でカバーできるのです.
今までの開発手法では,この状況をさけるために一生懸命「仕様書」 を書きました.個人にのみ知識が蓄積されてい くのを防ぐために,ドキュメントを大量に書くのです.これに よって,人が抜けても「仕様書」を読めば別の人がカバーできる というのです.でも,これまでの経験から,仕様書があてになる 可能性はとても低いと思います.仕様書は システムの「ある時期の仕様」を時間を止めて見ているような もので,実際には工程が進むにつれて仕様は変わって行ってしまいます. しっかり書いたドキュメントでも,実装に入る段階ではすでに ズレがたくさん出てきてしまうのです.
XPでは,「仕様は変わるものだ」ということを頭から受け入れます. そして,「仕様は学習していくものだ」という考え方を取ります. これによって,より人々に蓄積された知識をより重視するのです.
ソフトウェア開発は,「システムを作る」ことが目的なのですが,それは 「システムを理解する」という過程を抜きには考えられません.また その理解は,仕様書を作るという作業だけでは得られません. システムを作りながら理解をして行く,という, より柔軟なプロセスが,重要なんだと思いました. すこし背伸びしたことを書きました が,今後は,より大きなプロジェクトでXPを試してみて,本当に そうなのかを確かめていきたいと思っています. XPについての日本語ポータルサイトは,
http://www.ObjectClub.jp/community/XP-jp/ にあり,そこには入門記事や論文へのリンクがそろっています.メーリング リストも立ち上がっていますので, 次は,みなさんのXP体験談をぜひ聞かせてください. おしまい Last modified: Fri Aug 30 09:26:42 2002 |