アジャイルモデリングへの道3 マイルドなアジャイル開発手法 AMOP

オージス総研 技術部
藤井  拓

(本内容は当社Webマガジン「オブジェクトの広場」に掲載した記事を再掲したものです)

今回は, アジャイルモデリングを実践するためのベースとなるアジャイル開発手法として筆者らが考案したAMOP (Agile Method for Ordinary Projects) [1] という開発手法を紹介します. AMOP は, 既存の開発のやり方に慣れた開発者や管理者に受け入れられやすいものであることを目指したアジャイル開発手法です. 今回の記事では, まずスクラム [2] の短所や難しい点を説明し, 次いでそれらを XP (eXtreme Programming) [3] のプラクティスでどのように補おうとしたかについて説明します. さらに, AMOP を2つのプロジェクトに適用した結果を紹介します.




1. スクラムの短所や難しさ

前回の記事では, もっともシンプルで取り入れやすいと筆者が考えるアジャイル開発手法スクラムを紹介しました. その記事では, スクラムの長所を中心に説明しましたが, スクラムにはいくつかの潜在的な短所や難しさもあります.

  • メンバーの開発経験に対する前提
  • 変化への対応と高品質を両立するためのプラクティスの欠如
  • 30 日間という反復期間に起因する難しさ

スクラムは, プロジェクト管理に特化した開発手法であるため, モデリング, 実装, テストをどのように行うかはプロジェクトメンバーの裁量に委ねられています. 従って, スクラムだけを頼りに開発を進めるためには, 開発チームのメンバーが作業をどのように進めるべきかを理解していることが前提となります. 言い換えれば, プロジェクトメンバーがある程度の開発経験を積んでいることが求められます. 裏を返せば, 自律に基づくプロジェクト管理を行うことにより, 開発経験を積んだ開発者からなるチームの潜在的な力を引き出すことがスクラムの長所だとも言えます.

また, スクラムのもう一つの短所は, 変化への対応と高品質を両立するための具体的なプラクティスが提供されていない点です. すなわち, スクラムではスプリントと呼ばれる 30 日の反復サイクルの単位で実現すべき機能の範囲(スコープ)や仕様は見直すことができます. しかしながら, そのような反復毎に仕様の追加や変化を行った場合, 過去の反復で開発した既存コードの変更が発生し, その変更によりバグが発生する可能性があります. そのような状況に陥ると, プロジェクトが進むにつれて既存コードのバグ修正の労力が増えて, 新たな機能を追加するどころの話ではなくなったりします. スクラムでは, そのような既存コードの変更におけるバグの発生を抑制するための対策がプラクティスとして設定されていません.

さらに, スクラムの場合には反復の期間が 30 日と設定されているのですが, 30 日というフィードバックサイクルが長すぎるという場合もあります. 一般的に, 反復のサイクルが長ければ長いほど, 反復内で遂行されるべきタスクをより正確に見通す必要があります. 30 日分のタスクであっても, 正確に見積もるためにはその期間の開発内容を抽出できる必要があります. メンバーとの議論を通じてこのようなタスクの洗い出し作業を行う際は, 開発内容の確度の高い予想を行うとともに, 開発ペースを客観的に見積もることが必要になります. 反復期間が長ければ長いほど, 洗い出さなくてはならないタスク量は増え, しかも見積もりと実績のギャップを修正する間隔は伸びてしまうという難しさがあります.

スクラムに XP のプラクティスを部分的に取り入れることで, これら 3 つの短所や難しさを克服しようとして考えたのが, 本記事で紹介する AMOP という手法です.

以降, XP の特長と課題を説明し, なぜ XP を丸ごと取り入れなかったかという理由を説明します. つぎに, AMOP のプラクティスを考える際にスクラムと XP のプラクティスをどのように取捨選択したかを説明します. さらに, AMOP の実際のプロジェクトへの適用結果を紹介します.



2. XP の特長と課題

XP は, 第1回目の記事で説明したアジャイル・アライアンス [3] の価値や原則を補完する複数のプラクティスを提案しています. XP のプラクティスの詳細については, すでに多くの記事や Web ページがあるので本記事では説明しません. それらのプラクティスの特長は, 以下のとおりです.

  • 設計, 実装, テストなどの具体的な作業を実践するための指針となるプラクティスを提供している
  • "テスト駆動開発" [5], [6] や"ペアプログラミング"などの品質向上を狙ったプラクティスを加えることで, 要求変化に対応する柔軟性とソフトウェアの高い品質を両立させようとしている

ここで, "テスト駆動開発"とはテストコードをソフトウェア本体の実装コードに先行して実装する開発方式であり, "ペアプログラミング"とは 2 名の開発者がペアを形成し, 1 台のコンピュータ, キーボード, マウスを共有して開発を進める開発形式です. さらに, "テスト駆動開発"を実践する際に単体テストの自動化を支援する JUnit などのツールの利用を推奨しています.

XP のプラクティスは, 非常に良く考えられており, 強力なものだと筆者は考えています. しかし, その反面, 既存の手法に慣れた開発者や管理職にはすぐに受け入れるのが困難だと思われるプラクティスもあります. 特に, XP が推奨する"テスト駆動開発"や"ペアプログラミング"に対しては以下の 2 点で大きな抵抗があるのではないかと筆者は考えています.

  • 製品本体のコードではなく, テストコードから先に考えることが求められる
  • 労力に見合った効果が一般的に得られるかどうかの確証がない

前者は, 開発者に発想の転換を求めるため, すぐに受け入れるのは難しいと思われます. また, 後者は, 管理者に決断を求めますが, 多くの管理者は確証がないことを積極的に挑戦するほど余裕がないのが現実だと思います. これら 2 点により, XP をそのままで取り入れるのは多くプロジェクトにとって難しいのではないかと筆者は考えました.

一方で, 要求変化に対応する柔軟性とソフトウェアの高い品質を両立しようという XP の考え方は, アジャイル開発手法の付加価値を生み出すための有効な戦略だと考えられます. そこで, 筆者らは, 要求変化に対応する柔軟性とソフトウェアの高い品質を両立でき, 既存の手法に慣れた開発者や管理職により受け入れやすいアジャイル開発手法 AMOP を作ってみました. AMOP の基本的な発想は, スクラムと XP のプラクティスを組み合わせ, XP よりもマイルドなテストの自動化のプラクティスを追加することで要求変化に対応する柔軟性とソフトウェアの高い品質を両立できるのではないかということです.

表1 XP とスクラムの比較
表1 XP とスクラムの比較

なぜ, スクラムと XP の組み合わせなのだろうと疑問をもたれる方がいらっしゃると思いますが, 表 1 に示すようにプロジェクト管理が中心のスクラムと開発者のプラクティスが中心の XP はちょうど補完しあうような関係になっています. そのため, これら両者をうまく組み合わせることにより, バランスの取れたアジャイル開発手法を作り出せる可能性があります.


3. AMOPの構築

3.1 XPから取り入れた点

前述したように"テスト駆動開発"や"ペアプログラミング" は既存の手法に慣れた開発者や管理職に受け入れがたいという問題点があります. これらの問題点に対し, 要求変化に対応する柔軟性とソフトウェアの品質向上を現実的に両立するために, AMOP では以下のような方針を適用することにした.

表2 XP のプラクティスの取捨選択結果
表2 XP のプラクティスの取捨選択結果
  • "ペアプログラミング"は実践しない
  • "テスト駆動開発"は, "反復で実装したコードに対して可能な限り自動化された単体テストを実装する"という形に大幅に緩める

同様に, XP の各プラクティスについて効果の確信がなかった"コーディング標準", 及び指導なしの実践が困難だと思われた" 設計改善"を外しました. また, "顧客テスト", "シンプルな設計", "メタファ"については必須とせず, 適当と思われる局面でのみ限定的に実践することにしました.

結果として, XP のプラクティスは表 2 に示されるように取捨選択されました.

3.2 スクラムから取り入れた点

前回の記事と重複しますが, スクラムではプラクティスを明示的に定義しておらず, 以下のような役割及び開発の進め方を提案しています.

  1. 製品責任者が開発対象となる大きなレベルの機能のリストを"プロダクトバックログ"として書き出す
  2. 開発は 30 日間のスプリントと呼ばれる反復を単位に進行する
  3. 製品責任者は各反復で実現すべき"プロダクトバックログ"の項目を割り当て, 開発メンバーはその項目の詳細仕様と必要なタスクを抽出する
  4. 開発メンバーは毎日決まった時刻に作業実績, 作業予定, 問題点を報告する"デイリースクラム"という打ち合わせを開催する
  5. 開発途上で発生した問題点を解決し, プロジェクトが順調に開発を進めることに責任を持つ"スクラムマスター"と呼ばれる役割を設定する

これら 5 項目の中で, XP のプラクティスを大局的な開発範囲の設定, コミュニケーションの促進と問題点の顕在化, 問題点の解決の促進という点で補う A, D, E を AMOP に取り入れることにしました.

その一方, 以下の 2 点を意図して AMOP では B は採用せず反復の期間は 2 週間に設定しました.

  • 開発依頼者から開発内容に対するフィードバックをなるべく早く得る
  • 反復の計画と実績を対比するサイクルを短くすることにより, 開発者の計画能力を早期に育成する
表3 AMOP のプラクティス
表3 AMOP のプラクティス

また, C については XP の計画ゲームとかなり似ており, 計画に関する作業内容がより大雑把に記述されているにすぎません. そこで, AMOP では作業内容がより詳しく記述されている XP の計画ゲームを計画作業のステップに取り入れました.

以上説明したような XP とスクラムのプラクティスの取捨選択の結果から作成されたのが表 3 に示される AMOP のプラクティスです.


4. AMOP の実践結果

4.1 AMOP を適用した2つのプロジェクトのプロファイル

表4 AMOP を適用した 2 つのプロジェクトの概要
表4 AMOP を適用した 2 つのプロジェクトの概要

筆者らは, 2003 年 9 月から 2004 年 3 月の期間に AMOP を 2 つのプロジェクトに適用しました. これらの 2 つのプロジェクトで, 2003 年 9 月から 2003 年 12 月に実施したものを A プロジェクトと呼び, 2004 年 1 月から 3 月に実施したものを B プロジェクトと呼びます. これら 2 つのプロジェクトの概要を表 4 に示し, プロジェクトメンバーの開発及び技術経験を表 5 に示します. A, B 両方のプロジェクトのスクラムマスターは, 問題解決だけを行うだけではなく, 製品の設計, 実装, テストの作業も担当しています.

A プロジェクトではスクラムマスター, 開発メンバーともに社員でしたが, B プロジェクトではスクラムマスターが社員, 開発メンバー 2 名は協力会社の要員の方々でした. スクラムマスターとこれらの協力会社の方々は, B プロジェクト以前には一緒に仕事をした経験はありませんでした. また, B プロジェクトのスクラムマスターは, A プロジェクトの開発メンバーとして参加し, 計画ゲームの実践を経験していましたが, B プロジェクト以前にプロジェクト管理の経験はありませんでした.

ちなみに, 筆者は製品責任者と開発手法のコーチ役としてこれら 2 つのプロジェクトに参加しました. 筆者がプロジェクトに参加した作業と要した時間は以下のとおりです.

  • 予備検討期間: ハイレベルの要求を取りまとめたり, 使用する技術や開発手法を話合うために 2 日間程度
  • 各反復:初日の目標設定に 1 時間程度
  • 開発期間の最後の 2-3 反復:反復毎に作成されたソフトウェアを使用して評価するために 0.5-1 時間程度

これら 2 つのプロジェクトのチームは, 両方とも初心者とベテランの混成チームです. すなわち, A プロジェクトはベテラン開発者のスクラムマスターと開発初心者のメンバーのチームであり, B プロジェクトは新米スクラムマスターと協力会社のベテラン開発者のメンバーのチームです.

表5 プロジェクトメンバーの開発経験及び技術経験
表5 プロジェクトメンバーの開発経験及び技術経験

4.2 開発の進め方

両プロジェクトとも開発初期に予備検討期間を置き, その後2週間単位の反復により開発を進めました.

予備検討期間では, プロジェクトで実現してほしいソフトウェアについてのハイレベルの要求を取りまとめるとともに, プロジェクトで使用する技術の調査や技術修得を行いました. ハイレベルの要求は, 製品責任者が考えた実現してほしい機能の一覧であり, すべてが実現されるわけではありません.このハイレベルの要求は, スクラムで言う製品バックログに相当します.予備検討期間の終了時には, ソフトウェアの実現に使う技術とハイレベルの要求がほぼ確定しています.

各反復の初日には, 以下のように計画ゲームにより開発目標やタスクを設定し, 反復中はタスクの進捗をモニターしました.

  1. 製品責任者とスクラムマスターが今回の反復で実現すべき機能をユーザストーリという形で書き出す
  2. 製品責任者が各ユーザストーリの優先度を設定し, スクラムマスターが労力を見積もる
  3. 2 週間という反復の期間内で実現可能なユーザストーリを製品責任者が選択する
  4. スクラムマスターと開発メンバーが各ユーザストーリに必要な必要なタスクのリストを定義し, 2.で見積もった労力が妥当かどうかチェックする
  5. スクラムマスターは 4.で労力の見積もりの不整合が発生した場合, 製品責任者とともに再度目標となるユーザストーリの範囲を見直す
  6. 最終的に確定したユーザストーリとタスクは, スクラムマスターと開発メンバーがSWiki [7] というコラボレーションツールに記入する
  7. 反復途上で各タスクが完了したら, そのタスクの担当者が完了日付を Swiki 上に記入する

あとプロジェクト管理面の工夫としては, 予備検討期間を除いた開発期間の 1/2 か ら 2/3 まで進捗した時点で, ハイレベルの要求の中で"納品可能な機能範囲"を製品責任者と開発メンバーが話し合うようにしました. このような話し合いにより, 残された労力でユーザにとって役立つソフトウェアにするためにはどうしたら良いかということをより現実的に考えることができます.

4.3 A プロジェクトの実践結果

図1 ユーザストーリ, タスクの計画と実績 ( A プロジェクト )
図1 ユーザストーリ, タスクの計画と実績 ( A プロジェクト )

まず, 計画ゲームによって設定された反復の目標がどの程度達成されているか調べるため, 反復毎のユーザストーリ数, 反復最初で設定されたタスク数及び実際に完了したタスク数をモニターしました. 図 1 は, A プロジェクトのモニター結果を示したものです.

この図から, 第 2 反復以降計画したタスクはほぼ完全に消化されており, 計画ゲームによる反復単位の目標設定はうまく行われていることが分かります.

次に, プロジェクトでテストの自動化がどの程度まじめに行われているかモニターすることを試みました. モニターする方法としては, JUnit の実行結果のレポートが手軽なのですが, プロジェクト期間を通じたトレンドやアプリケーションクラスに対するテストクラスの密度が分かりません. そこで, JUnit の実行結果のレポートから算出できる測定値として「パッケージ毎にアプリケーションクラス1クラス当りの平均テストケース」を求めてみました. ここでテストケース数とは, JUnit 等で自動実行できるテストケースクラスの testXX 操作数に対応します.

図2 1 クラスあたりのテストケース数の推移 ( A プロジェクト )
図2 1 クラスあたりのテストケース数の推移 ( A プロジェクト )

図 2 は, A プロジェクトの主なパッケージについてアプリケーションクラス1クラス当りの平均テストケースを求めた結果です. ui パッケージのクラスについては, A プロジェクトで用いた JUnit などのツールにより単体テストが自動化できなかったため, テストの実行状況はモニターできていません.

この結果より, パッケージ毎のばらつきがあるもの, 概ね開発途上でもテストケースの密度は低下しておらず, 順次拡充されていることが分かります.

しかし, いかんせん「アプリケーションクラス1クラス当りの平均テストケース」ではテストの質の評価としてあまりにも大雑把過ぎます. そこで, より精密にテストの網羅性を測定しようと考え, A プロジェクトの開発が終盤に差し掛かった時点でテストカバレージの測定ツールを導入しました.

表6 ステートメントカバレージとコード行数の測定結果 ( A プロジェクト )
表6 ステートメントカバレージとコード行数の測定結果 ( A プロジェクト )

A プロジェクトの終了時点で, 単体テストが自動化されたパッケージ中の 3 つのパッケージのステートメントカバレージを計測した結果を表 6 に示します. ここで, action パッケージでは単体テストが自動化されていましたが, カバレージ測定ツールの不具合で正常な計測値が得られなかったので除外してあります. actionパッケージはStrutsのActionを実装するクラスから構成されていますが, テスト容易性を高めるため通常Actionにべた書きされるドメインロジックの呼び出しをServiceクラスに分離しています.

この測定結果より model と persistence パッケージについては, 比較的良好なステートメントカバレージが達成されていることが分かります. その一方, service パッケージのステートメントカバレージは不十分であることが判明しました. serviceパッケージは, 前述したServiceクラスが集まったパッケージです.

このように service パッケージのステートメントカバレージが低い値に留まったのは, テストケースが十分であるかどうかという判断を開発者の主観に委ねたことが主原因だと考えられます. 実際に, ステートメントカバレージが低かったのは主として開発経験が浅い開発者の担当部分でしたが, 開発経験が長い開発者であっても主観だけが頼りであれば同様の状況は起こりえると思います.

4.4 B プロジェクトの実践結果

図3 ユーザストーリ, タスクの計画と実績 ( B プロジェクト )
図3 ユーザストーリ, タスクの計画と実績 ( B プロジェクト )

B プ ロジェクトでも, 計画ゲームによる反復の目標設定がどの程度有効に行われているか調べるため, 反復毎のユーザストーリ数, 反復最初で設定されたタスク数及び実際に完了したタスク数をモニターしました. その結果を図 3 に示します. B プロジェクトでは第 1 反復は製品の細かい仕様策定に当て, 実際にプログラムが作られたのは第 2 反復以降でした. また, 第 5 反復は開発メンバーの契約期間の制約で 1 週間と, 反復の期間が通常の半分になっています.

このような結果より, B プロジェクトにおいても計画ゲームによる反復単位の目標管理はうまく機能したことが分かります.

一方,  B プロジェクトの開発対象は GUI アプリケーションであったことや JUnit のような単体テストツールでテストの初期状態の制御を簡単に行えなかったため, GUI テストツールの導入によるテストの自動化を試みました. しかしながら, GUI テストツールにいくつかの問題があったため, 開発期間中は GUI テストツールを適用しませんでした.

B プロジェクトの完了後, このGUIテストツールの問題が解決したため, GUI テストツールでテストスクリプトを生成, 実行し, その際にステートメントカバレージの計測を行いました. その結果, 3 日間程度で主要な機能を 97% 程度のステートメントカバレージで網羅するテストスクリプトを作成できました.

この 4 月の GUI テストツールの適用結果から, GUI テストツールの問題がなければ, B プロジェクトでも開発途上のテストの自動化が達成できたのではないかと考えらえます.

B プロジェクトで開発したソフトウェアは, 2004 年 4 月に GUI テストツールでテストを追加した後, 社内外にリリースしました. コード規模は小さいですが, 2005 年 6 月現在に至るまで不具合は 1 件も見つかっていません. 正確な利用者数は分かりませんが, 少なくとも20人以上のユーザが使っていると思われます.

さらに, プロジェクト完了後, JUnit のような単体テストツールで本当にテストの初期状態の制御ができないかという点について詳しく調べたところ, ある程度の工夫を行えば初期状態の制御ができたはずだったことも判明しました. B プロジェクトでは UML モデリングツールの拡張機能が開発対象であり, この拡張機能はモデルがロードされている状態で動作するものでした. JUnitを適用する場合, テスト用のモデルをロードして初期状態を作り, 拡張機能を動作させ, 実際の動作結果を期待する動作結果と比較して動作が正しいかどうか判定すればよかったのです. しかし, 開発の途中でそのようなテストの可能性に開発メンバーが気づいたり, 組み込むことができませんでした.

この調査結果より, テストの自動化についてはプログラミングが本格化する前の予備検討期間において, テストについて詳しい人間の支援も受けて具体的な実施方針を検討することが大事であることが分かりました. 言い換えれば, 「テストの方針は走り始める前に考えよ」ということです.

4.5 AMOP の評価と考察

AMOP を実践してみて, うまく機能したのは以下の 3 点です.

  • 2 週間単位の反復
  • 計画ゲームによる目標設定
  • スクラムマスターとデイリースクラム

の一方, 不十分だったのが「テストの自動化」に関する以下の 2 点です.

  • テストの質の評価
  • テストの実施方針の検討

前者については, プロジェクトの初期段階から最低限でもステートメントカバレージの測定を行うべきだったと思います. また, 後者については, 予備検討期間でソフトウェアの実現に必要な技術及び機能の概要が明らかになった段階で, 大雑把でも良いのでアーキテクチャをモデル化し, それに対してどのようなテストを行うべきかを明確にすべきだったと思います. 但し, テストについてはプロジェクトメンバーだけで考えるのが困難だと思うので, テスト専門のコーチを派遣したりするなどプロジェクトの支援を考えるべきではないか思います.

A, B 両方のプロジェクト共に反復毎の目標の達成率が良かった点については, 以下のようなスクラムマスターのスキルや姿勢が大きく貢献したと筆者は考えています.

  • スクラムマスターがプログラムコードやテストコードを理解できたこと. その結果, スクラムマスターとメンバーとのコミュニケーションや問題解決が円滑に行えた
  • スクラムマスターが問題解決に利用可能な資源をフルに使ったこと. すなわち, 自分自身で考えるだけではなく, 開発メンバーの意見やインターネット上の情報をうまく取り入れた

逆に, スクラムから派生した AMOP のような開発手法を用いる場合には, これらの 2 点をある程度備え, 心がけることでプロジェクト管理経験がない若手エンジニアでもプロジェクト管理が可能になるのではないかと期待できます.

最後に, 今回実践した 2 つのプロジェクトは実装期間が 3 ヶ月で, 開発メンバーが 2-3 人程度と規模が小さかったのであまり問題にならなかったですが, より大きな規模では以下の 2 点をさらに補強する必要が出てくるでしょう.

  • 開発すべき内容についての理解をチーム内で共有する
  • 開発すべき内容の実現性やスコープについての見通しを持つ

筆者は, モデリングこそがこれらの 2 点を解決する鍵になると考えています. 実際に, 本連載の 5 回目では AMOP にモデリングを取り入れた結果について紹介する予定です.


5. まとめ

本記事では, 平均的なスキルを持ち, アジャイルではない既存の開発手法に慣れた開発者及びプロジェクト管理者に受け入れられるアジャイルな開発手法 AMOP を構築し, その適用結果を報告しました.

AMOP を 2 つのプロジェクトに適用し, 目標管理に関するプラクティスは概ね期待通り実践できました. それに対して, テストの自動化については以下の 2 点で不十分点があることが分かりました.

  • テストの質の評価
  • テストの実施方針の検討

前者を改善するためには, カバレージ測定ツールなどを適用し, テストの質を評価することが有効だと考えられます. 後者を改善するためは, 開発初期の予備検討段階でテストの実現方式を決めていく必要があると考えられます. 但し, 様々なプロジェクト状況に対応したテストの実現方式を開発メンバーだけで決めるのが難しい場合もあり, テストの専門的な知識や経験を持つコーチの派遣などの支援体制も大事になると思われます.

また, AMOP ではデイリースクラムやソースコード以外の技術的な概念の共有手段がありません. そのため, 開発規模がより大きくなると以下の2点が不十分になることが懸念されます.

  • 開発すべき内容についての理解をチーム内で共有する
  • 開発すべき内容の実現性やスコープについての見通しを持つ

これらの懸念は, モデリングを取り入れることにより解決されるのではないかと筆者は考えています. 次回は, アジャイル開発にモデリングを取り入れることを積極的に提案しているアジャイルモデリング [8], [9] の考えを紹介する予定です.


参考文献

  • [1] 藤井 拓, 鶴原谷 雅幸, 大津 尚史: 普通のプロジェクトへの適用を目指したアジャイルな開発手法の構築と適用結果, SPES 2004 配布資料, 情報サービス産業協会, 2004, pp.275-293
  • [2] ケン・シュエイバー他: アジャイルソフトウェア開発スクラム, ピアソンエデュケーション, 2003
  • [3] ケント・ベック: XPエクストリーム・プログラミング入門―ソフトウェア開発の究極の手法, ピアソンエデュケーション, 2000
  • [4] アジャイル・アライアンスのサイト: http://www.agilealliance.org/home/
  • [5] ケント・ベック: テスト駆動開発入門, ピアソンエデュケーション, 2003
  • [6] 川端 光義他: バグがないプログラムのつくり方 - JavaとEclipseで学ぶTDDテスト駆動開発, 翔泳社, 2004
  • [7] ボウ・ルーフ他: Wiki Way - コラボレーションツールWiki, ソフトバンクパブリッシング, 2002
  • [8] スコット・アンブラー: アジャイルモデリング - XPと統一プロセスを補完するプラクティス, 翔泳社, 2003
  • [9] AM 日本語リソースサイト: http://www.ogis-swe.jp/process/am-res