学生ポータルの例
地域大学は、学生向けのオンラインサービスを提供するための学生ポータルを開発したいと考えています。そこで、学生代表、学部の職員、ポータル管理者のメンバーを招集し、チームを編成して学生ポータル開発プロジェクトに参加してもらいました。ここでは、初回会議の議事録を抜粋して紹介します。
ステークホルダー会議
議題
- 学生ポータルの機能を提案する
- 提案された機能リストの実現可能性について議論する
- 実装する機能を、コア機能、次回バッチ、好ましい機能などに優先順位をつける
スティーブ(開発チーム):ようこそ… 会議をより生産的で成果の出るものにするために、希望する機能を提案する際には、以下の形式を標準的な表現方法として使用してください:誰(あなたが誰か)、何の機能(あなたが望むもの)、そして(なぜそれを望むのか)… これらの機能は、プロジェクト全体を通じてのコミュニケーションツールとして、ユーザーストーリーとして記録されます。
その後、さまざまなステークホルダーからユーザーストーリーのリストをブレインストーミングしました:
学生代表:授業の登録、授業料の支払い、時間表の確認、スケジュールの編集、成績表の確認、授業の履修取消…
教務代表:授業情報の追加、授業情報の編集、授業情報の削除…
ポータル管理者:授業情報のバックアップ、学生アカウント状態の編集
今、複数のカードがあり、それらを行と列に整理できる状態です

提案された機能の優先順位付け
開発者代表:次回イテレーションで実装する優先順位のついたユーザーストーリーのリストがあります。そのためには、各ユーザーストーリーについて詳細に掘り下げ、より多くの情報を得る必要があります。それでは、最初のコア機能「授業の登録」のユーザーストーリーを確認しましょう。

会議で、エンドユーザーから以下の追加情報が得られました:
- 教務:学生は全日制の登録学生でなければならない
- 管理者:学生はログインに必要な正しいアカウント資格情報を提供しなければならない
- 教務:授業は定員に達していないこと
- 教務:授業の前提条件を満たしていること
- 管理者:スケジュールに追加される授業は、他の授業の時間枠と重複してはならない
- 開発者:この機能とまとめて、ターゲットシステム内でリストとして配置したい他の機能はありますか?
- 学生:授業の履修取消、スケジュールの確認、スケジュールの編集。
ユーザーストーリーの3C
良いユーザーストーリーは単なる記述以上のものです。標準的なユーザーストーリーは、一般的に「3C」と呼ばれる3つの部分から構成されます。各ユーザーストーリーの最初の「C」は、[役割]として、私は[何かをしたい]、その理由は[利益がある]という標準的な形式に従うべきであり、これはカードに記載するユーザーストーリーの最小限の内容です。2番目の「C」である「会話(Conversations)」は、エンドユーザー、プロジェクトオーナー、開発チーム間の議論を表す内容であり、会話の記録や、メール、ワイヤーフレーム、プロジェクトに関連するその他の有用な情報が含まれます。ユーザーストーリーの最後の「C」は「確認(Confirmation)」であり、ユーザーストーリーが正しく実装され、成功裏に提供されたことを確認するための受入基準です。
ユーザー ストーリーの確認部分を開発する方法について、もう少し詳しく説明します。ここでは、最もよく知られているテンプレートであるGherkinを使用しており、ユーザー ストーリーの受入テストを書く際のガイドラインとして「Given-When-Then」の形式を採用しています。
- (Given.. そして) ある文脈
- (When.. そして) あるアクションが実行される
- (Then.. そして) いくつかのアクションを実行する
CucumberやJbehaveといったテストフレームワークは、自動テストを実施する際にGiven/Then/Thenテンプレートの使用を推奨していますが、使用するツールにかかわらず、単なるヒューリスティックとして用いることも可能です。
「コース登録」ユーザー ストーリーに関するすべての情報を集め、3Cs形式に整理しましょう。

それでは、以前に開発した変換と確認を含む情報を、UeXcelerに反映しましょう。

エピックをユーザー ストーリーに分割する
「コース登録」ユーザー ストーリーをさらに詳しく検討すると、スプリントに組み込むには大きすぎる可能性があります。これをエピック(より大きなユーザー ストーリー)とみなすことができ、関連する小さなユーザー ストーリーのグループに分割できます。エピックをタスクに分割する場合を水平分割と呼び、あるいはエピックをシナリオに分割して垂直分割と呼ぶこともできます。
水平分割
大きな機能を構築する従来のアプローチは、アーキテクチャ層ごとに作業を分解することでした。たとえば、モデル・ビュー・コントローラ(MVC)やクライアント・サーバー アーキテクチャなど、システム アーキテクチャにおける関心の分離を実現し、その後、GUI、コントロール ロジック、オブジェクト モデル、オブジェクトリレーショナル マッピング、データベース層など、n層アーキテクチャに細かく調整します。n層アーキテクチャには多くの層がありますが、以下にいくつかを挙げます。
- アーキテクチャ層の一つにおいて高い専門性を発展させることができる
- 他のアプリケーションが、あなたの層によって公開された機能を再利用できる
- 層を複数の物理的層に分散できる。これにより、パフォーマンス(場合によっては)、スケーラビリティ、障害耐性の向上という、アプリケーションに非常に良い影響を与える
- 層間の結合度が低いため、アプリケーションの保守が容易になる
- アプリケーションに追加機能を追加しやすくなる
- 層構造により、アプリケーションのテストがしやすくなる
n層アーキテクチャに基づく成功事例は多数存在し、Ruby on RailsやWebサービスベースのアーキテクチャなどがその例である
ユーザー ストーリーと水平分割
n層アーキテクチャの利点をシステムに活かす一方で、ユーザー ストーリー アプローチと組み合わせる際にはいくつかの欠点も生じます。特に、機能の規模によってはフィードバック ループが非常に遅くなりがちです。なぜなら、各メンバーが個別に作業を終え、統合して動作確認を行うまで待たなければならないからです。このアーキテクチャ層アプローチを主な分解手法として用いることを「水平スライシング」と呼びます。
垂直分割
フィードバック ループを高速化するために、エピックを複数のユーザー シナリオに分割し、各アーキテクチャ層を横断するようにします。ほぼすべての機能を、数日以内にすべての要素を構築・統合・テストできるスライスに分解できます。各スライスには、アーキテクチャ層で必要な作業、およびリリース準備のために必要なテストや統合作業が含まれます。
一般的に、水平分割は機能をアーキテクチャ コンポーネントレベル(例:フロントエンドUI、データベース、バックエンドサービスなど)のユーザー ストーリーまたはタスクに分割します。一方、垂直スライスは、動作し、実証可能でビジネス価値を提供するソフトウェアを生み出します。したがって、垂直分割により、チームは各スプリントで潜在的にリリース可能な製品のインクリメントを提供する能力が向上します。クリーム、チョコレート、果物、生地が重なったケーキを想像してください。水平にカットすると、友人はケーキ、チョコレート、クリーム、果物のいずれかの層だけを手に入れることになります。友人は、すべての層を少しでも含んだ部分を好むでしょう。単一の層だけでは、ケーキ全体の本当の味わいを体験できません。友人たちにとってより良い選択肢は、垂直スライス(望ましい価値)を作ることです。

目的に基づいたエピックの水平分割
ステークホルダー会議で「コース登録」ユーザー ストーリーの変換について思い出してください。この機能は学生(主役)によって最初に提案され、他のステークホルダーによって支援されました。ユーザー ストーリーの詳細を掘り下げると、支援役として関与する他のステークホルダーが事前に準備していた情報が多数あることがわかりました。
現実には、一部の学生は「支援役」の人々が設ける制約に興味を持たない、あるいは望まない場合があります。たとえば、学生がパスワードを忘れ、3回間違えて入力した場合、パスワード再設定プロセスを経るのを避けたいが、さらに何度も再試行できる自信を持っている、あるいは図書館の貸出冊数や貸出期間に制限を設けたくない、といった具合です。提案された機能にビジネスルールや制約を設けることを目的とするのは、ユーザー ストーリーの支援役として参加する人々です。もしビジネスルールや第二の目的が提案された機能に適用されなければ、その機能はまったく動作しないべきです。二次的アクターの目的に従ってエピックを水平分割し、関連するユーザー ストーリーのグループに分けることで、二次的アクターの目的を満たすだけでなく、ユーザー ストーリーをテスト可能にし、正しい人物から直接フィードバックを得ることができます。

変換と確認のセクションから得られた情報を検証し、「コース登録」という大きなストーリーを、関連するユーザー ストーリーのグループにどのように分割できるかを検討しましょう。
- 学生は登録済みの学生でなければならない。そうでなければ、新規学生向け通知によって与えられる資格が得られない。通知を受け取ったがアカウントがまだ有効化されていない場合は、オンラインで新しいアカウントを登録する必要がある(赤丸1でマーク)
- ログインプロセスをさらに詳しく調べると、学生が認証情報を3回間違えると、「パスワード再設定プロセス」に移行する必要があることがわかります(赤丸2および3でマーク)

一般的なユーザー ストーリーの領域
UeXcelerでこれらのユーザーストーリーを作成しましょう:
ログインアカウントのユーザーストーリーは、一般的なユーザーストーリーのコンパートメント内に作成されています。ログイン関連のユーザーストーリーに加えて、以下の理由から、一般ユーザーストーリーのコンパートメント内に「パスワードのリセット」および「新しい学生アカウントの作成」という2つの関連するユーザーストーリーも作成されています:
- 学生がアカウントの認証情報を3回連続で誤って入力した場合、「パスワードのリセット」ユーザーストーリーがトリガーされます;
- また、新しい学生がまだ学生アカウントの登録をしていない場合、ログイン画面内で「新しい学生アカウントの作成」ユーザーストーリーをトリガーできます。
- 学生として、私は学生ポータルにログインしたい。なぜなら…
- ポータル管理者として、ログインしている人物が登録済みの学生であることを確認したい。なぜなら…
- コースリーダーとして、選択されたコースを学生のスケジュールに追加する前に適切性を確認したい。なぜなら…
これらの3つのユーザーストーリーは、エピック「コース登録」から水平に分割されたものと考えられます。しかし、これらのユーザーストーリーは、フィードバックを得て確認できる一部の支援アクターの目的を達成します。事前条件が満たされない場合、メインのユーザーストーリーはまったく意味を持たなくなるでしょう。
これらすべてのユーザーストーリーを一般的なユーザーストーリーのコンパートメント内に配置している理由は、同じ呼び出しページ内の他の関連する機能(ユーザーストーリー)と同様の事前条件を共有する可能性が高いからです。たとえば、「スケジュールの表示」「スケジュールの編集」「授業の削除」などです。
ユースケースコンパートメント
上図に残っている赤線で囲まれた4、5、6は、エピック「コース登録」の代替シナリオです。これらの3つの条件のいずれかが偽となった場合、その対応する代替シナリオが発生し、分割されたユーザーストーリーとして表現できます。たとえ水平分割または垂直分割のどちらかを行う可能性がありますが、垂直分割の方が常に好ましいのでしょうか?必ずしもそうではありません。状況によって異なります。世界には万能の解決策はなく、どのアプローチがご自身の状況に適しているかを検討する必要があります。もう少し詳しく説明します。
たとえば、メインのユーザーストーリーを1人の開発者に割り当て、ログイン、新規アカウント登録、パスワードリセットの3つのユーザーストーリーを別の開発者に割り当てる場合、メインのユーザーストーリーを担当する開発者が現在のスプリントでハッピーシナリオを最初に開発し、その後のスプリントで同じ開発者が段階的に代替シナリオを開発することを好むかもしれません(時間枠が許す場合)。しかし、時間枠が短く、かつ同じ開発者がエピック全体を担当するのは負担が大きすぎると思われる場合は、水平にタスクを分割して複数の開発者に並列で割り当てることができます。
エピックをシナリオに分割する
エピックの確認セクションに記載されたシナリオの詳細を検討すると、関連するユーザーストーリー群に対する垂直スライスを簡単に見つけることができます。
- コースリーダーとして、選択されたコースを学生のスケジュールに追加する前に、必須要件を確認したい。なぜなら…
- コースリーダーとして、コースの空き状況を確認してから、コースを学生のスケジュールに追加したい。なぜなら…
- コースリーダーとして、学生の時間枠の空き状況を確認してから、選択されたコースを学生のスケジュールに追加したい。なぜなら…
エピックをタスクに分割する
エピックを、同じスプリント内で並列開発可能なより小さなタスクに分解したい場合、以下のようになります:
- 授業定員状況の確認
- 授業の必須要件の確認
- 時間枠の確認
今、エピックをアジャイル開発プロセスのためのユーザーストーリーに分割する方法は、あなた次第です。『コース登録』ユーザーストーリーとその関連するユーザーストーリーが、ユースケースコンパートメント(あなたのエピック)に配置されていることがわかります。このコンパートメントは、『コース登録』と呼ばれ、メインのユーザーストーリーおよびそのメインから分割されたユーザーストーリーをすべて収容するためのプレースホルダーとして使用されます。
