以前いたチーム(複数のバックエンドAPIを開発するチーム)でやっていたスタイルがなかなか良かったなあと思うので忘れないようにメモ。
スクラム
まず、このチームにはプロダクトオーナー、プロダクトマネージャーみたいなロールの人がいない。自分たちでやることスケジュールを決定していた。
スプリント
2週間を1スプリントとする。
水曜日始まり、水曜日終わり。水曜日にしている理由は、月曜からミーティングがつらいのと、金曜終わりだとすべてを忘れるため。真ん中の日に実施してスイッチを入れ直す。
スプリントゴールはちゃんと決めてない。毎回プランニングしたときに、積み上がったタスクをやりきるぞ!みたいな目標になっている。順序が逆っぽいと思っている。
プランニング
スプリントの始まりには、1時間つかって、このスプリントでどれをやるかプランニングを行う。
プランニングよりも前に、あらかじめ次のスプリントで必要なタスクをスプリントの枠に入れる。大きな開発がある場合は進捗がわかっているはずなので、次にやる予定のものを入れる。あるいは締切があるようなタスクも入れる。
スプリントを閉じたとき、完了しなかったチケットは次のスプリントに移動する。
スプリントでやりたいチケットが揃ったら、上から順番に見て、見積もりがついていないチケットに見積もりをつける。
すべての見積りが揃ったら、直近3スプリントの平均ベロシティを超えないよう、このスプリントでやるチケットを整理する。これは四半期単位での目標や、締切などに沿って入れ替える。
最後にアサインを決める。基本はやりたい人が取っていく方式。例えば、一人が一緒にやったほうがよいだろうなども考慮する。どっちでもいいな、と空中に浮いた場合は、見積もりから負荷がわかるので、分散されるようにする。
このプランニングで積んだチケットは、絶対にやらなければいけないというものではない。過去の自分たちのやってきたスピードと、これからやる内容への見積もりから、ここまでできるだろう、という予測。
リファインメント
スプリントのちょうど真ん中の日、1時間つかって、リファインメントを行う。
これはスプリントとバックログの見直しを行う。スプリントで行っていることが増えたり減ったりする場合に共有する。さらに、バックログにあるチケットに見積もりを付け、優先度を整理したり、不要になったチケットをクローズする。
ある程度整理されるとやることがあまりなくなるので、1時間使わない日もでてくるがこれはこれでOK。
レトロスペクティブ
スプリントの終わりには、1時間つかって、レトロスペクティブ、振り返りイベントを行う。
とあるチケットが中途半端の場合は、チケットを分割し、どこまでやったかをやった人自身が見積もりを付けてやった部分をクローズする。残りのチケットは次のスプリントに回す。これはベロシティを正確に測るようにするため。経験が積まれていくことでだんだんと事前のチケット分割も進められるようになる。
最終的にすべてのチケットに見積もりが付いている状態にしてからスプリントをクローズする。クローズしたチケットについていた見積もりの合計値をそのスプリントのベロシティとして記録する。
ベロシティを見たり、やったチケットを見たりして、そのスプリントにおけるよかったことや課題、問題点などを話し合う。
スプリントレビュー
特にやっていなかった。
デイリースタンドアップ
毎日お昼ごろに以下のことを共有する会を30分ほどする。
- 各自のタスク状況
- 昨日なにした
- 今日なにやる
- ブロッカーがあるか
- その他共有
- おやすみ予定
- こういう依頼があった
- あっちのチームでこういうことやってる
- 直近のイベントごと
- 二次会
- 各自でトピックをもちよって共有会をしたり、議論や相談を行う
- 今やっているタスクをこうやろうと思うけど、どうだろう?
- xxという機能があるけど我々には有用だろうか?
チケット
チケットの説明には以下の要素を入れていれる
- WHY: なぜこのチケットをやるか
- WHAT: このチケットでは何をやるか
- GOAL: このチケットは何をしたらクローズされるか
- 見積もり: このチケットはどれくらいの大変さか
チケットの内容が大きい場合には後述するデザインドックを準備する場合もある。
見積もり
見積もりは相対的なストーリーポイント方式。1,2,3,5,8,13 というフィボナッチ数を使用する。
プランニング、リファインメントのとき、見積もりが付いていないチケットについて、チケットでのやることをチームに説明し、メンバーが理解をしてから、セーノドドン、と見積もりを提示する。メンバー感で大きなズレがある場合は合わせる。1段階くらいのズレのときは特に深く話すこともなく多数決で決まりがち、1ポイントが3人、2ポイントが1人、みたいな場合。最大と最小が2段階以上ずれている場合は、前提知識ややることへの理解がズレがあるので、各自のポイントがどういう背景からそう考えたのかを話あう。
このときにより分かりやすくなるように、チケットに説明を書き足したり、チケットをいくつかのチケットへと分割する。
相対見積もり
この設定値を書き足してリリースする、を1ポイント。この機能の実装をしてリリースする、が2ポイント。などとして基準となるポイントの設定をしている。この基準のタスクと比較して、各チケットのやることの難しさ、大変さなどを考慮して見積もりをする。
誰かがやったら5時間だけど、この人がやったら10時間かかるよな、みたなことを排除することが狙い。
ベロシティは上下する
相対見積もりを使い、アサインも様々となると、絶対的な時間が読みにくくなる。
例えば、
- フロントエンドはAさんがよく知っているから早くできる
- Bさんにフロントエンドをやってもらうのは時間がかかる
- このフロントエンドタスクはAさんだと5時間でBさんだと…はて?
みたいなケース。
このとき、Bさんにそのフロントエンドタスクをやってもらうと、チームとしてはポイント消化が減り、ベロシティが下がる。しかし、そのスプリントでBさんにはフロントエンドの知見が多少なりとも身につく。チームで活躍するにはまだ不十分かもしれないけれど、次以降のスプリントでBさんにフロントエンドタスクをやってもらったときに以前よりもスピードが出て、より多くのポイントを消化できる。
チームとしてチャレンジが多くなる投資タイミングではベロシティが下がる。逆にスピードを出したいときには専門性を重視するとベロシティが上がる。
そのため、ベロシティの上がり下がりにはそんなに深く注視をしていない。レトロスペクティブの際に、今回は下がったけれど何かあったっけ?上がってきたね調子いいね、といった話を行っている。
13ポイント以上はヤバい
ポイントをつける際、13ポイント以上のものは”ヤバい”という共通認識がある。単純に考えて1ポイントのタスクが13個詰まっているのとおなじ。この状態のまま進めてもいいがいくつかの問題がある。
- チケットの進捗が見えない
- カンバンを見ても、チケットがずっとWIPステータスのままなので進んでいるのか詰まっているのかわからない。
- デイリースタンドアップの話を聞いても何%くらい終わっているのか見えにくい。
- アサイン内容の偏りができる
- その大きなチケットを一人で抱えると、ほとんどのケースにおいて、スプリント内でやることがそのチケットだけになる。
そこで13ポイント以上になるチケットは内容を改めて確認し、適切に分割を行う。例としては「エンドポイントの定義をしてハンドラーを実装。リクエスト内容に応じてDBにクエリし、その結果に何かの処理をして、レスポンスを返す。あたらしいAPIの開発」。これは多くの要素に分割できるので、いい感じに分割する。
- 開発
- DBアクセス処理の実装
- HTTPハンドラーの実装
- 何かの処理の実装
- 開発環境へのリリース
- 本番環境へのリリース
開発タスクは並列してできるので、アサインを分けてもいいし、一人でもいい。リリースも、開発したひととは異なるひとがやってもいい。例えばリリースしたことがない人がチームにいればその人アサインで、開発した人がヘルプする、みたいなこともある。
毎回絶対に分割しているかというとそうでもなくて、まるっと一人がやったほうが楽、という場合もあるので、その場合はまるっとやっている。もし何かしらの理由でスプリント内に終わらなかったら、終わったところまでを分割してクローズする。残ったのは次スプリント。
ポイントが揃わないのはそう
提示したポイントが異なることはよくある。悪いことではなく、何かしらの理由がある。
- 内容がふんわりしすぎていてわからない
- 内容を明確にする
- 未確定のところがあれば、未確定要素を決める、といったチケットを作ったりする
- 内容が多すぎて測れない
- チケットを分割して、処理できるようにする
- やったことがなくてわからない
- いったんやってみる
- 調査タスク
- 無限に調査ができてしまうので2-3ポイントくらいで決めちゃう。難しいもの面倒なものは5ポイントとか。
割り込みタスク
どうがんばっても割り込みタスクは発生する。緊急性の高いものは当然進んでやるが、そうでもないものは基本的には次以降のスプリントに回していた。シュッとできるのはやっていたけれど。
スプリント内で割り込みタスクをやった場合、その分のベロシティがちゃんと計算されるよう、チケットと見積もりをやった人自身がつけている。
プランニング時に、割り込みが毎回xxポイントくらいあるからその分低めで、みたいなことはしていない。常に、ベロシティから算出される予定ポイントの通りにチケットを積む。割り込みがあればそれをちゃんとスプリントに入れる。レトロスペクティブのときに、あふれる分を整理する。
いきなりこの形ではない
いきなりこのスクラムの形ができてやっているわけではない。元々プランニングも振り返りもなく、やることのチケットを作って、各自でよしなにやっていた。
そこに、まずは、開発のリズムを作ってみよう、と2週間のリズムを決めた。プランニングもしたけど見積もりも超ざっくり、チケット分割も全然していない。レトロスペクティブのときにスプリント閉じるも大半がそのまま持ち越し、みたいなことも。バックログもやるのかやらないのか、どんなタスクかよくわからないのがたくさんあった。けれども、コミュニケーションが以前よりも増え、チームに少し活気も出てきたりもした。
こなせるようになってくると、問題点を解消するべく次のアクションを徐々に取っていった。ベロシティがわからないのでやった分のチケットを分割してクローズしましょう、リファインメントを実施して見えないバックログを見えるようにしていきましょう、大きなタスクは終わらないので事前に分割しましょう、プロジェクトごとは全体像が見えないのでデザインドックを書いたりロードマップを考えましょう、バックログが見えるようになってきたので四半期目標に合わせて並び替えよう、などと。
他にも書いてないけれど、四半期ごとに振り返り会をやってみたりして、次の四半期どうしよう、もう少し先の話、チームが将来的にどうなっていくのがいいかな、といったことも話し合うようになっていった。
こんなふうに、チームが成熟すると共に、開発の流れも成熟していった。
JIRA
JIRAを使ってチケット、スプリントの管理をしている。
JIRAが用意しているストーリーはあまり使っていない。理由は上下関係やワークフローの設定がややこしいのと、カンバンが見にくくなる。また、私の居たそのチームでは、プロダクトマネージャーを専門としている人がおらず、その手の知見がなかった。そのため、シンプルな TODO-WIP-DONE というタスクだけを作っている。ある程度おおきなプロジェクトとして進めるような場合は、主にタグ付のような用途ではあるがエピックを作って紐付けている。
JIRAのアジャイルボードではスプリントを随時作成することができ、常に、先々の3スプリント分くらい用意している。これは締め切りが先のタスクであったり、大きな開発をするとき、全体の進捗からこのあたりでやりたい、というのを先に設定していた。
JIRAではスプリントを閉じていくと、レポート、というページが育つ。このページでは、各スプリントのベロシティを見ることができるほか、チケットがどれくらい作られどれくらいクローズされたかなども見れる。
デザインドック
何を書くか
デザインドックとは、何を、なんのために、どのように作るのか、をまとめたもの。 https://www.atmarkit.co.jp/ait/articles/1606/21/news016.html
これはチケットと同様の内容を書いているように見えるが、チケットの枠で多くの様々なことを説明することが難しい。そこで、別途デザインドックを必要に応じて残している。
具体的にはある程度気合が必要な複数のタスクが絡む大きめのタスク、プロジェクト化して進めたくなるようなもの(エピック)、といったものにはこのデザインドックを書いていた。見積もりポイントの目安としては13以上になってきたり、そもそもポイントが読めないもの。あるいは開発する以外についても書いていた。こういう仕組みをチームにいれようと思うがどうだろうか、というもの。
このデザインドックには以下の項目を書く。
- Background
- どのような理由からこのデザインドックを書くことになったのか
- Goal
- このデザインドックは何が最終目標なのか
- Non Goal
- このデザインドックが対象としていないことはなにか
- Plan
- おおまかかな全体像として、どのようにそれを実現するか
- 図を使う
- 必要ならばコードの断片も書く
- いくつかのプランが考えられるなら書いて比較する
- History
- 更新履歴。レビューや議論したときの更新メモ
- 大雑把でOK
例えば「エンドポイントの定義をしてハンドラーを実装。リクエスト内容に応じてDBにクエリし、その結果に何かの処理をして、レスポンスを返す。あたらしいAPIの開発」
- Background
- チームXが私達のZZZデータをXXという機能を提供するのに利用したい
- ZZZデータを取得するAPIはまだないので作る必要がある
- Goal
- ZZZデータを取得するAPIの概要
- Non Goal
- XX機能に関すること(私達はZZZデータを提供するAPIにフォーカスする)
- Plan
- APIのインタフェース定義
- GET /get
- Request
- string user_id // ZZZデータを探すユーザID
- Response
- []ZZZ
- ZZZ{ name:string }
- データが見つからない場合は404を返す
- ZZZデータをどのよう返すか
- リクエストのuser_id を使ってZZZテーブルにクエリ
- 取得したデータに対して~~の処理を行う
- その結果をレスポンスに合わせ、呼び出し元に返す
- DBの負荷対策
- user_id でのインデックスがないので新たに作成する
- その他
- XX機能は 100 req/s でこのZZZデータをリクエストする予定
- 事前に開発環境で同等のリクエストを行いAPIサーバ、DBの負荷テストをする
- XX機能は 100 req/s でこのZZZデータをリクエストする予定
- APIのインタフェース定義
- History
- 2021/02/01: 初版作成
ごく簡単ではあるがこういうイメージ、かなあ。
書いたあとどうするか
この出来上がったデザインドックをチーム内でレビューし、気になる点があれば、担当した人に追記してもらう、考え直してもらう、などをする。最終的にLGTMとなれば、そのデザインドックの内容に合わせてチケットを作り前に進めていく。
実際に作業を進めると、デザインドックの内容ではうまく行かないことも出てくる。その時はデザインドックの内容を更新することが多い、かも。そのまま放置することもある。特に取り決めがない。
最終的に出来上がったものがデザインドック通りだとしても、その後のアップデートで変わることがあり、継続的な更新、メンテナンスが非常に困難のため、これから作るものが雑多に作られることがないよう初手のレビューをしよう、というのが狙い。たとえメンテナンスを行わなくとも、作った当時に、なぜ作ったのか、どのように考えたのか、どのような議論があったのか、を知る資料となる。
デザインドックは何度でも書く
デザインドックを書き、実装を終え、リリースも終えたあと、再びその実装に対して大きな変更を加えるときが来た際、再びデザインドックを書く。
これは「今の実装や仕組みがこうなっているので、このように変更する。これはコレコレこういう価値がでる。他の案としてはこういうのもあるがこれではだめ」といったデザインドックになる。
ここからさらに何をやっていくか
アイデアとしてはいくつかある。おそらく、ソフトウェア開発、という形の現状から、プロダクト開発、という形にシフトしていくのがよいのではないだろうか、と思っている。少なくとも、私の居たときには、テクノロジーにフォーカスするような場面、あるいは他チームのオーダーを受ける場面が多かった。チームで開発しているプロダクト:複数のバックエンドAPI、にフォーカスするような場面はあまり多くはなかった。たとえユーザが社内の別のチームだとしても、自分たちの作っているプロダクトの利用者であることには変わりないので、利用者の声を聞き、どんな利用者がいて、そこにどんな価値を提供していくか、といった攻めていける形になるのがよいのではと思っている。
それが、ユーザストーリーを作ってみる、プロダクトオーナーを設ける、スプリントレビューを行う、とかとか、そういうことになると思う。その一方で、ミーティングなどの直接的な開発ではないタスクが増えるのが予想できれる。仮に何も生まなくてもなにかをやっている気になってしまう。何度か試しにやってみて、何も生まなそうだったらやめたり、やり方を変えたりする、といったチャレンジが必要だろう。
ただそのときに私のいたそのチームにおいては、それらをどのようにやるかを持っている本職な人がいなかったので、本やWeb上の多数の資料から自分たちで知見を身につけたり、本職の誰かにコーチしてもらうなどしていくのが必要だろう。
もちろん、テクノロジーにフォーカスする場面、負債を考える場面といったものは重要なので、定期的にチームの姿を確認しつつ、四半期の目標設定をしたり、より長期でのロードマップ的なものを考えていけるといいんじゃないだろうか。
というメモ。