この記事では、スクラム開発において重要な要素の一つであるストーリーポイントについて解説する。
タイトルに「極意」という仰々しいワードを入れているが、筆者が個人的に感じていることや考えていることも含まれるため、参考程度に読んでほしい。
あるタスクを完了させるために必要な工数を表す指標の一つである。タスク A は 3 ポイント、タスク B は 5 ポイント、のように設定していく。
これと言った決まりはないが、よく使われる配分として、フィボナッチ数列が挙げられる。
フィボナッチ数列とは、前の項 (数字) とさらにその前の項を足し算した結果が次の項になる数の並びである。
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...]
たとえば、13
という数字は、一つ前の 8
とそのさらに一つ前の 5
を足し算した結果である。
一つ前の数字と大きくかけ離れるため、ポイントの設定に迷ったりすることが少ないから、というのが理由として挙げられる。
たとえば、タスク A があり、ストーリーポイントの配分に 13
と 15
という選択肢があったとき、このタスクのストーリーポイントを 13 にすべきなのか 15 にすべきなのかは迷うことが多い。
しかし、13
と 21
くらい数字が離れていれば、13 か 15 で迷っていたタスク A に 21 を割り振るのは感覚的に乖離が大きいと気づく。
そうなった場合に、迷うことなく 13 を設定できるかもしれないし、もし 13 よりも少し大きい数字 ― 15 くらい ― にしたいという気持ちがまだ残っているのなら、それはタスクの粒度がまだ粗い可能性がある。
たとえば、タスク A を、タスク α, β, γ に細分化することによって、γ は、α と β の実装によってはもしかしたら対応不要かもしれない、と気づくかもしれない。そうなると、α と β のストーリーポイントは明らかになり、ブレが少なくなる。
そうやって少しずつ精度を上げていくことができる。
タスクを完了させるために必要な工数だから、3 ポイントだから 3 時間かかる、5 ポイントだから 5 時間かかる、という指標ではない。
これはあとでも説明するが、ストーリーポイントは相対評価 である。タスク A が 2 ポイントで、タスク B が 8 ポイントだった場合、B の工数は A の工数の 4 倍あると見積もることができる、という指標である。
一般的に、ストーリーポイントはチーム全体の指標として用いられる。個人の力量に依存しない。
これはどういうことかというと、たとえば、チーム内にスーパーエンジニア (優秀なエンジニア) と入ってきたばかりの新米エンジニアがいたとする。タスク A は、スーパーエンジニアにとっては簡単だからストーリーポイントは 5 だが、新米エンジニアにはまだ難しいから 13 にする、といった決め方はしない。
あくまで、そのチーム全体で、そのタスクがどれくらいの開発コストで完了するのかを基準に採点する。だから、似たような機能実装でも、会社 A のチームではストーリーポイントが 5 で、会社 B では 8 になるかもしれない。それはそれで問題ない。
ストーリーポイントが時間見積もりではないことと、個人の力量に依存しないことを示す例えとして、筋トレがわかりやすいのではないかと思う。
20 kg のダンベルを持ち上げることを考える。筋肉ムキムキの街雄さんは軽々と 100 回連続で持ち上げられるが、最近太り気味のひびきさんは 1 回持ち上げるのがやっとだ。
この場合、20 kg というダンベルの負荷が、ストーリーポイントに相当し、何回持ち上げられるかがタスク完了までの時間に相当する。
誰が持ち上げたとしても 20 kg というダンベルの重さは変わらない。街雄さんが持ち上げると 5 kg 分になるから、100 回連続で持ち上げられる、ということにはならない。同じ重量でも人によって連続で持ち上げられる回数が異なるのは、筋肉量が違うからだ。
ここでいう筋肉量が個人の能力や知識量に相当するもので、能力や知識量が多ければ多いほど、他の人よりも早くタスクを終わらせることができる可能性が高い。
まとめると以下の通りだ。
筋トレ | スクラム開発 | 補足 |
---|---|---|
ダンベルの重量 | ストーリーポイント | 人によって変わるものではない |
何回連続で持ち上げられるか | タスク完了までの時間 | こなせる量 |
筋肉量 | 能力・知識量 | 人によって個人差がある |
上述の通り、ストーリーポイントはチーム全体の指標のため、そのタスクや案件を進めるエンジニアだけで決めるわけではない。
タスク A があり、そのタスクのメイン担当者が太郎さんだった場合、太郎さんを含めたチーム全員でタスク A のストーリーポイントを推定し、妥当なポイントを設定する。
各々の決めたストーリーポイントをチームに公開する際には、プランニングポーカー がよく用いられる。
チーム全員でストーリーポイントを設定する際の手法である。
以下の手順で行う。ポイントの配分方法にフィボナッチ数列を採用しているものとする。
「こんなことをしなくても、『このタスクはこれくらいだと思う』と各々が言っていけば良いじゃないか」
はじめは誰しもそう思うだろう。
しかし、一人が ― とりわけ声 (チーム内の発言力) が大きい人が ― 最初にストーリーポイントをチーム内に公表してしまうと、他の人がそれに流されてしまう可能性がある。以下のような理由で。
(そのタスクに対して関心がないなあ……)
(この人がこう言っているんだからきっとそれが正しいんだろう……)
(めんどくさいから自分もそう言うことしよう……)
(自分の考えていたストーリーポイントは、他の人と全然違う…… 同調圧力が怖いから言えない……)
このような理由で自分が考えていたストーリーポイントがチーム内に共有されず、結局 1 〜 2 人の意見のみが反映されてしまうことがある。それではチーム内でストーリーポイントを決定しているとは言い難い。
このような状況を防ぐために、みんなで一斉に意見 (ストーリーポイント) を公表できるプランニングポーカーがしばしば用いられる。
本来、プランニングポーカーは全員が同じ場所 (会議室等) に集合してオフラインで行うものだが、最近はリモートワークの需要も増え、オンラインでできる Web 版プランニングポーカーツールやサービスも登場してきている。
必ずしもオフライン版のプランニングポーカーの形式にこだわる必要はないので、そこはチーム内で話し合い柔軟に対応すると良いだろう。
タスクの見積もりに正解はなく、このタスクは絶対にこのストーリーポイントである、といったことは言えない。だからこそ、基準となるタスクを用意 し、相対的に評価することが重要である。
たとえば、ユーザの検索機能を実装することを考える。users テーブルには、ID や性別、誕生日のカラムが入っている。
性別による検索機能のタスクのストーリーポイントが 2 だったとしたら、ID による検索も、相対的に同じくらいのストーリーポイントで実装できるだろうと判断できるかもしれない。あるいは複数 ID でも検索できるようにするなら、複数の ID を配列に格納して SQL を発行する必要があるので、少し増えて 3 になるかもしれない。
また、年齢による検索機能を実装する場合、テーブル上には「年齢」を表すデータがないので、現在の日時と誕生日から逆算して検索する必要がある。そうなった場合は、誕生日から年齢を逆算するロジックを追加で実装する必要があるため、ストーリーポイントは 5 くらいになるかもしれない。
このように、何か基準となるタスクがあり、そのタスクのストーリーポイントから相対的に判断すると、見積もりがしやすいし、精度も高くなる。
導入当初は、基準となるタスクが少なく見積もりが難しいと感じるかもしれない。しかし、導入してしばらく運用を続けていると、次第にこのタスクはこれくらいのストーリーポイントだと判断できるようになってくる。過去のいくつかのタスクで「実績」が蓄積したことにより、見積もりのしやすさと精度が上がってくる。
これは個人的な見解だが、ストーリーポイントを如何に正確に推定するかよりも、タスクを如何に細分化できるかのほうが重要 だと筆者は考えている。
これは例を見たほうがわかりやすい。
89
はストーリーポイントを表している。
まず大前提として、これだと、何を根拠に 89
というストーリーポイントを算出したのかが全くわからない。
そして、どこに時間がかかりそうなのかもわからない。ユーザからの入力値をバリデーションするところなのか、入力値を整形するところなのか、あるいはテストを書くところなのか。
どこの実装にどれくらいかかるかが明確ではないということは、想定外のコストがかかりやすい。たとえば先の例で、年齢は誕生日から逆算するロジックが必要だと述べたが、細分化していないと気づきづらい。
「ID 検索でストーリーポイント 3 くらいで、全部で項目が 27 だから、合計 81 ポイント! 少し余裕を持たせてフィボナッチ数列に当てはめると 89 ポイント!」
のように細分化せず概算で決めてしまうと、年齢検索のように単純なロジックでは実装できない部分で想定外の時間がかかってしまい、予定通りに案件を達成できない可能性が出てくる。
また、別の案件として別のテーブルの検索機能を実装することになった場合に、ユーザ検索機能の実装が 89 ポイントだったから、今回も 89 ポイントくらいで大丈夫だろう、と判断するのが危険なことは、よもや言うまでもないだろう。
一応補足として、ストーリーポイントはあくまで指標であり、これくらいのストーリーポイントを設定したから必ずこの期間で完了する、ということを確約するものではないし、過信しすぎるのは良くない。
だが、1 〜 2 ヶ月で終わるとみられていたものが、実際にやってみたら半年もかかってしまったとなると、タスクの細分化や見積もりの精度が甘いことを指摘せざるを得ないだろう。
上記のように細分化すると、いろいろなことが見えてくる。たとえば、以下のようなことがわかる。
このようなことがわかってくることで、以下のメリットがある。
上記はあくまで例なので、ここまで細分化しなくても良いかもしれない。反対に、もっと細分化したほうがタスクが進めやすいと思うなら、もっと細分化しても良いだろう。
細分化したタスクとそのストーリーポイントに関する補足説明を以下に示す。
冒頭の繰り返しになるが、ストーリーポイントの正確さ以上に、タスクの細分化のほうが重要 だと筆者は考えている。ストーリーポイントはあくまで相対評価なので、多少なりとも精度のズレは往々にして発生する。
タスクをできる限り細分化できていれば、想定外の工数がかかるリスクが減らせるし、タスクの抽象度が下がることで見積もりもしやすくなる。つまり、タスクを細分化することで、ストーリーポイントの正確さは自ずと向上する と筆者は考えている。
注意してほしいのは、タスクを細分化すればするほど、基本的には想定外の工数はかかりにくくなるが、絶対にかからないというわけではない。
たとえば、年齢検索で、「12 歳以上」や「34 歳以下」のように、上限なしや下限なしでも検索できるようにすることを考える。
少し前の Ruby では、beginless range ((12..)
で 12 以上の range を表現できる) や endless range ((..34)
で 34 以下の range を表現できる) が実装されていなかったので、以下のように書く必要がある。
# 12 以上を表す
(12..Float::INFINITY)
# 34 以下を表す
(-Float::INFINITY..34)
実際には年齢ではなく誕生日から逆算するので、Date 型で範囲指定をしなければならない。
ところが、古いバージョンの Ruby では、Date 型の下限に -Float::INFINITY
を指定することができないというバグがあった。
(Date.today..Float::INFINITY)
# => #<Date: 2021-08-26 ((2459453j,0s,0n),+0s,2299161j)>..Infinity
(-Float::INFINITY..Date.today)
# ArgumentError (bad value for range)
ちなみに新しいバージョンの Ruby ではこのバグは修正されている。
当初、上記のような範囲指定で実装しようとしていた場合はここで躓いてしまう。この問題を解決する工数が新たに発生するだろう。
このことをすでに知っており、解決方法もわかっているスーパーエンジニアならここで想定外の工数が発生することはないだろうが、これを知らないエンジニアが、ストーリーポイント設定の段階で推定するのは困難だろう。
このような想定外の工数がかかることに対して、「仕方ない」の一言で片付けるのはお粗末かもしれないが、どのようなタスクにもこのような想定外の工数がかかることを考慮しておくのが良いだろう。
これは、チームリーダーのようなチームメンバーを評価する立場の人だけでなく、各チームメンバーにも覚えておいてほしい事柄である。
今まで説明してきた通り、ストーリーポイントは、時間見積もりでもなければ、個人の力量に左右されるものでもない。タスク A のストーリーポイントが 5 ポイントなら、それはチーム内の誰にとっても 5 ポイントだし、のび太くんが 3 日かかるとしても、出木杉くんには 1 日で終わるタスクかもしれない。
そこで気になってくるのが、人事評価に利用されないか、という点である。
ストーリーポイントを導入すると、よくも悪くも個々人のアウトプットが明瞭になりやすくなる。出木杉くんは四半期で 300 ポイント分のタスクを消化できたが、のび太くんは 100 ポイントしか消化できなかった、ということもわかるようになってくる。
ここで言いたいのは、個人の能力や力量を会社の評価に使ってはいけない、ということではない。あくまで その評価にストーリーポイントを直接的に介在させてはいけない、ということである。
単純にストーリーポイントの消化具合だけで人事評価をする人がチームリーダだった場合、何が起こるだろうか。筆者の頭の中には、このような会話が思い浮かぶ。
デビル出木杉くん: (ぼくがやるこのタスク、ふつうに見積もったら 5 ポイントだと思うけど、13 ポイントってことにしておけば、ポイントが稼げるな…… 😈)
のび太くん: (ぼくは要領が悪いし出木杉くんみたいに優秀じゃない……。ぼくがやるタスク、1 週間くらいかかりそうだけど 5 ポイントだから、また評価下がるかなあ…… 😢。13 ポイントくらいにしておいて欲しいなあ……)
デビル出木杉くん: 「ねえ、のび太くん。うちのチームリーダーはストーリーポイントの消化量でしか評価しないみたいだから、プランニングポーカーのとき、お互いのタスクをポイント高めにしてみない? そうすればぼくも君も、評価が良くなるよ!」
のび太くん: 「それいいね! ぜひそうしよう!」
デビル出木杉くん & デビルのび太くん: 😈😈😈😈😈
これは極端な例だが、このようにチームメンバー内での結託が起こらないとも限らない。仮に結託が起こらなかったとしても、自分が担当するタスクに対して、声を大きくして主張すれば、ポイントを意図的に上方に操作できるかもしれない。
これではストーリーポイントを設定している意味がなくなってしまう。尤も、チームリーダーが、人事評価の手段に用いるためにストーリーポイントをチーム内に導入しようとしているなら意味はあるのかもしれないが、これは本来の用途ではないし、チームとしても健全ではない。少なからずチーム内の生産性は下がるだろう。
上記の理由から、ストーリーポイントを直接的に人事評価に用いるのは避けるべきである。
ここまで説明してきた中で重要なポイントをかいつまんでまとめる。
ストーリーポイントを導入し、上手に運用していくことで、以下のようなメリットが得られる。
適切な運用方法を守って、チーム内を健全に機能させたい。