いざRuby on RailsでプロトタイピングRubyでアジャイルプロトタイピング(5)

本記事はRuby on Rails(以下、RoR)を使ってプロトタイプを作成し、アジャイルかつ正確にクライアントからの機能要件を取りまとめることを提案する連載「Ruby でアジャイルプロトタイピング」の第5回です。前回はDBのマイグレーション機能について解説しました。連載第5回目の今回は、開発の現場でどのようにプロトタイピングを行うべきかについてお話ししたいと思います。

» 2006年04月05日 12時00分 公開
[鍜治舍浩(永和システムマネジメント), 西川仁(永和システムマネジメント), 林秀一(アークピア),@IT]

アジャイルプロトタイピングのサイクル

 連載第3回「アジャイルプロトタイピングとRuby on Rails」でPDSサイクルについて解説しました。

ALT 図1 RoRによるアジャイルなPDSサイクル

 筆者はシステム開発において(特に開発初期の段階では)何よりもリズムを意識しています。PDS(Plan・Do・See)サイクルを頭の中でイメージしながらプロトタイピングを行うことで、プロジェクトにリズムが発生します。実装フェーズで追加されるメンバーも、このリズムに乗ってプロジェクトにスムーズに参加していくことができるようになります。メンバーの顔が曇っているプロジェクトには、大抵リズムが存在していない(だらっと出社して、実装してだらっと帰る)ことが多いと思いませんか。

 今回は、PDSサイクルでアジャイルプロトタイピングを行う方法を解説します。

プロジェクトの概要

 今回取り上げる仮想プロジェクトの顧客はビデオレンタルショップです。ビデオレンタルショップは会員向けサービスとして、レンタルビデオの検索、予約、ある商品についてのレビューの作成とその閲覧機能を持ったポータルサイトを構築したいと考えています。検索、予約機能については、顧客側である程度のイメージがまとまっているようです。こちら側も以前に別の案件で同様の機能を作成した実績があるのでそれほど心配はしていません。

 問題になりそうなのは、レビューの作成とその閲覧機能です。顧客側で「そういう機能を作りたい」という要望は存在しているのですが、それをどのように実現すべきかを顧客自身が整理できていないようです。そういう状況なので、こちら側としてもそれをどのように要件に落とし込んだものやら、どう実現してよいやら(どんな画面構成で、どんなフローで)いまひとつまとめ切れません。

 まずは顧客とシステムのイメージを共有する必要がありそうです。手持ちの情報をいったんこちら側で整理してプロトタイピングを行い、それをたたき台にして細部を詰めることを提案してみました。

・Plan

 まずは画面フローから考えます。余談ですがDave ThomasもDHHとの共著「Agile Web Development with Rails」(*1)でサービスとサービスがどのように関連しているのかをはっきりさせるためには、まず画面遷移をざっくり考えてみることが必要だと述べています。

ALT 画面フロー

 会員向けポータルサイトなのでログイン、ログアウト画面や検索、予約機能は必須です。しかし、今回のプロトはレビュー機能にフォーカスしたものなのでこれらの要素については極力考えないようにします。そのため、まずは商品とレビューの関係についてデータモデルを作成することにしました。

ALT データモデル

 ActiveRecord では主キーにidというカラムを使用します。システムの方でレコードを一意にするために採番したときの主キーを「サロゲートキー(surrogate key)」とか「人工キー(artificial key)」と呼びます。これに対して、顧客IDや商品番号などの、ビジネス上の意味から自然に一意となる値を主キーにしたものを「ナチュラルキー (natural key)」と呼びます(*2)。

 ActiveRecordではサロゲートキーを採用しています。しかし設定によりナチュラルキーを使用することも可能です。大体の場合において、サロゲートキーを採用した方がシステムはビジネス上の仕様変更に強くなります。実システムにおいても、顧客からの要望が特になければ、サロゲートキーを採用することを考慮した方がよいと思います。(*3

 Railsならここから一気にcontroller、modelを生成することができます。

・マイグレーションでテーブルを作成する

> ruby script/generate migration create_tables
        create db/migrate
        create db/migrate/001_create_tables.rb
(001_create_tablesを編集)
> rake migrate

・controller,modelを生成する

> ruby script/generate controller review
> ruby script/generate model review
> ruby script/generate model member
> ruby script/generate model item
> ruby script/generate model actor
> ruby script/generate model director

・Do

 model、controllerができたら早速コーディングします。まずはレビュー表示画面を作成します。

「レビュー」

<h1><font size="8" color="red"><%= h @item.title %></font></h1>
<p>
<h3>作品情報</h3>
<table>
    <tr>
        <td>製作: <%= h @item.creation %></td>
    </tr>
    <p>
    <tr>
        <td>監督:
            <% @item.directors.each {|d| -%>
                <%= link_to d.name, :action => "" -%>
            <% } -%>
        </td>
    </tr>
    <p>
    <tr>
        <td>出演:
            <% @item.actors.each {|a| -%>
                <%= link_to a.name, :action => "" -%>
            <% } -%>
        </td>
    </tr>
</table>
<h3>この作品の最近のレビュー</h3>
<% @item.reviews.each {|r| -%>
    <table border="0" cellpadding="0" cellspacing="0" width="100%">
        <tr valign="top">
            <td>
                <font size="2"><font color="red">
                    <%= h r.title -%>
                </font><br></font>
            </td>
          <td align="right">
            <font size="2">
                <%= h r.created_on -%>
                <br>
                <font color="green">
                    <%= h r.reviewer.name -%>
                </font>
            </font>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <font size="2"><%= h truncate(r.comment, 10) -%><br></font>
            </td>
            </tr>
    </table>
<% } -%>
<p>
<%= link_to "もっとレビューを見る", :action => "" %>
<%= link_to "レビューを書く", :action => "" %>

 viewから作成するとviewにどの情報を渡してやればよいか、どんな処理が必要かが明確になり、controller、modelが簡潔に実装できると思います。

「コントローラ」

class ReviewController < ApplicationController
    def show
        @item = Item.find(params[:item_id])
    end
end

「モデル」

class Actor < ActiveRecord::Base
    has_and_belongs_to_many :items
end
class Director < ActiveRecord::Base
    has_and_belongs_to_many :items
end
class Item < ActiveRecord::Base
    has_and_belongs_to_many :directors
    has_and_belongs_to_many :actors
    has_many :reviews
end
class Member < ActiveRecord::Base
    has_many :reviews
end
class Review < ActiveRecord::Base
    belongs_to :item
    belongs_to :member
    def reviewer
        Member.find(self.member_id)
    end
end

 同様の手順でレビュー詳細表示画面、レビュー作成画面を作成していきます。この時点でいくつかの仕様上の確認点が出てくると思います。

  • レビュータイトル、レビューの字数の最大値はいくつにしましょう?
  • 1つの作品にいくつぐらいレビューを作成できるようにしましょう?
  • 会員が過去に作成したレビューを削除する機能は必要でしょうか?
  • 同じ会員が1つの作品について複数のレビューを作成することを許しますか?

 よりよい機能にするための提案もこちらからできるかもしれません。

  • レビュー作成画面に「不適切なレビューは削除される場合もあります」うんぬんの注意書きを表示する必要があると思われます
  • 管理者が不適切なレビューを削除するためのメンテナンス画面が必要と思われます (要件にはありませんでした)

 これらの確認項目や提案はデモ時に顧客に確認します。RoRを使ってプロトタイプの作成を素早く行うことで確認項目や提案事項の洗い出しを行うことができました。素早く行うことで、「ネタの鮮度」を落とさずデモをし、確認・提案を行うことができます。

・See

 プロトタイプができたので、早速デモをします。レビューの表示から作成。作成したレビューがまたレビュー表示画面に表示されます。実際に動作しているプロトタイプでデモをすると、より具体的な要件を顧客から引き出すことができます。

 プロトタイプ作成中に浮上した確認・提案を顧客に提示します。デモで顕在化された課題や要件は次のPlanのインプットになります。

・そしてまたPlan

 今回のデモの結果、次のデモのinputがみえてきました。

■確認項目の検討結果

  • レビュータイトル、レビューの字数の最大値はいくつにしましょうか?
    →ハードウェア構成と併せて検討
  • 1つの作品にいくつぐらいレビューを作成できるようにしましょうか?
    →同上
  • 会員が過去に作成したレビューを削除する機能は必要でしょうか?
    →空っぽのレビューが登録されたら「削除」扱いとする
  • 同じ会員が1つの作品について複数のレビューを作成することを許しますか?
    →許さない。会員と作品とは1:1の関係にするように

■提出項目の検討結果

  • レビュー作成画面に「不適切なレビューは削除される場合もあります」うんぬんの注意書きを表示する必要があると思われます
    →必要がある。文言は顧客側で検討
  • 管理者が不適切なレビューを削除するためのメンテナンス画面が必要と思われます (要件にはありませんでした)
    →アドミン業務チームと検討

■新たにいただいた宿題

  • エラーメッセージの表示領域をもっと大きくしてほしい
  • レビュー作成画面にレビューしている作品のタイトルを表示してほしい

 今回のデモではそれほど大きな問題、課題は挙がりませんでした。ただ、レビューを保存するのにどれほどのストレージを必要とするかはハードウェアの発注作業もあるので、早めに検討したいところです。上記のinputを基に次のDo、Seeを行います。もう1回もデモをすればレビュー機能はほぼ固まりそうです。

「本当はどうしたいの?」を探す

 最初から(システムの)細部に至るまでの明確なイメージを持った顧客というのは基本的に存在しません。システムを開発する側の人間は、顧客と何度も打ち合わせを繰り返して、そのイメージを明確化・詳細化・具現化していきます。その過程で顧客とシステムのイメージを共有していくのです。従来ですと、その過程で生まれてくる成果物はドキュメントでした。しかし、筆者は形のないもの、目に見えないものについて「あーだ、こーだ」と議論するのは本質的に不毛であると考えています。ドキュメントはイメージを共有するための媒介物ではあるかもしれませんが、 “イメージそのもの”ではありません。どちらかというと「覚書」(これこれこういう風に実装します)、「念書」(これこれの実装で問題ありませんね)のたぐいの性質を持っていると考えています。

 アジャイルプロトタイピングの最終成果物は、「過程から得られる知見」です。中間生産物として動くプロトタイプというものが存在します。このプロトタイプこそが顧客と開発する側である私たちが共有するシステムのイメージに当たります。アジャイルプロトタイピングとは、具現化されたシステムのイメージを基に「本当はどうしたいの?」を探す顧客との協調作業なのです。

プロトタイプはプロトタイプ

 繰り返しになってしまいますが、アジャイルプロトタイピングの最終成果物は「知見」です。中間生産物であるプロトタイプの完成度に必要以上にこだわることは時間のムダと考えます。どうしても「ここがオブジェクト指向っぽくない」などと細部に目が行ってしまいがちですが、最低でも以下の項目が喚起できればプロトタイプの役割としては十分だと考えられます。

  • 顧客の要件、要望
  • その実現可能性
  • データモデル
  • 画面構成
  • モジュール構成
  • 工数

 今回は、開発の現場でどのようにプロトタイピングを行うべきかについて解説しました。今回の例ではアジャイルプロトタイピングによって、従来の紙芝居型プロトタイピングだけではなかなか出てこなかったであろう顧客の要望、要件をスムーズに引き出すことができました。もちろん実際の開発現場は顧客やそのほかのステークホルダーの思惑があってもっともっと複雑なものです。今回紹介したように「さくっと」物事が決定していくことはまずありません。しかし、そういった複雑な現場にこそ、なおさらアジャイルプロトタイピングが必要なのではないでしょうか。

Copyright © ITmedia, Inc. All Rights Reserved.

注目のテーマ