Yo Ogino
読書メーターの事例に学ぶ属人性のないチーム開発(技術書典5頒布記事)
こんにちは。読書メーター開発チームの荻野です。
今回の記事では、技術書典5で頒布したトリスタinside出張版 Vol.01に記載した「読書メーターの事例に学ぶ属人性のないチーム開発」を、ブログ向けに修正を加えつつ全文公開します。
記事タイトルの「属人性のないチーム開発」はキャッチーさを優先させたもので、実際には完全に属人性を排除しているとは言い切れませんが、チーム開発改善事例のひとつとして、みなさんの参考になれば幸いです。
読書メーターはもともと個人開発から始まったサービスで、6年に渡るサービス運用ののち、2014年にドワンゴが買収しました(現在はトリスタが開発・運用をしています)。 当時の私のミッションは、このアプリケーションのリプレースでした。
本記事では、手探りで始まったチーム開発においてどのような課題が生じ、それらをどのように解決したのかを、時系列順に解説します。 エンジニアの視点で書いてあるのでソフトウェア開発主体の話になりますが、なるべくエンジニア以外の方にも伝わる内容を心がけますので、チームで仕事をしているすべての方が対象読者です。 また、タイトルに「属人性」というキーワードを入れましたが、属人性に限らずさまざまなチーム開発の改善点について触れています。
チーム開発初期
読書メーターのリプレース計画は、まずは、データの永続化などを含むバックエンド部分とPC向けサイトのリプレースから始まりました。 このフェーズの開発チームの人数は、初期は4人、終盤は7人でした。
まずは、未熟ながら開発リーダーであった私が、やらなければいけない作業を洗い出し、GithubのIssueに起票しました。 Github Issueにはいくつかの機能がありますが、使っていた機能はLabel(チケットの種類のカテゴライズ)とAssignee(チケットの担当者管理)のみでした。 以降、作業内容が書かれたGithub Issueをチケットと呼びます。
チケットのフォーマットはばらばらで、完了条件が明確に書いてあるものもあれば、詳細な説明がないチケットも存在しました。 開発メンバーは、優先順などをリーダーに随時確認しつつ、チケットをとっていくという方式で開発を進めました。
チケットには見積もりはつけず、進捗管理は、「一週間にこれくらいの数のチケットを消化していけば終わるはず」という大雑把な管理を行っていました。 また、リリースまでの全工程が完了するまでは明確な作業の区切りがないままに、ひたすら大規模なアプリケーションのリプレース作業を行っていました。
このフェーズでは、次のようなことが起こりました。
-
プロジェクト全体の正確な進捗が把握できず、当初の見積もりも甘かったため、計画よりもリリースが大きく遅れた
- チケットの消化率で進捗を把握しても、要件の洗い出しやチケットの完了条件の設定が甘く、手戻りも多かったため、正確な進捗がわからなかった
- プロジェクトが大きく、明確な区切りも存在しなかったため、作業の終わりがなかなか見えず、メンバーが疲弊した
- リーダーが関係者とのやり取りや仕様調整、チケットの整理などをすべて行っていたため、作業負荷が高く、属人性が高かった
とにかく、「やるべきことをチケット化し、それを消化していけばいつか終わる」という考えでがむしゃらに開発を進めたため、いろいろなことが破綻していました。 PC向けサイトのリプレース終了後、問題の解決手法について明確なビジョンはなかったものの、次のフェーズでは手探りで若干の改善を試みます。
2つ目のプロジェクト
次に、スマートフォン向けサイトの開発に着手しました。このフェーズでは、人員の入れ替わりもありましたが、人数としては前フェーズと同じく7人でした。
この段階で、前フェーズで使っていたGithub Issueには、次のデメリットがあると考えました。
- Issueに親子関係を定義できない
- Issueに見積もりをつける機能がない
全体像の把握や進捗管理のためには上記の機能が必要だと判断し、開発のチケット管理をRedmineに移行しました。 チケットをカテゴリに紐づけ、各チケットに見積もりをつけることで、カテゴリごとの進捗を可視化できる点がRedmineの便利な点でした。
また、開発期間を小さく区切るため、一週間区切りでチケットを管理するようになりました。 開発サイクルを決まった期間で区切る手法は、スクラムにおけるスプリントの考え方に近いため、この一週間の区切りを便宜上スプリントと呼びます(後述しますが、本来、期間を区切っただけではスプリントとは呼べません)。
チケットには作業時間の目安を見積もりとして記入し、メンバーの人数と稼働日数から実働工数を逆算し、一週間の作業時間に収まる範囲内のチケットをスプリント内作業として積みました。
スプリントの導入と同時に、振り返りも導入しました。 毎週スプリントの終わりに、ホワイトボードを使ってKPTを行いました。 KPTとは、Keep(良かったので継続したいこと)・Problem(問題点)・Try(新たに取り組みたいこと)をそれぞれ挙げていくことで、チームの改善を行う手法です。 KPTを採用した理由として、メジャーであったこと、以前私が所属していたチームで使っていたことが挙げられます。
いくつかの改善策が試みられましたが、このフェーズでは、次のようなことが起こりました。
- リーダーが関係者とのやり取りや仕様調整、チケットの整理などをすべて行っていたため、依然として作業負荷が高く、属人性が高かった
- チケットの見積もりはすべてリーダーがつけていたため、メンバーにとって妥当性のある数字でないことがあった
- スプリント(もどき)は存在したものの、スプリント単位で成果物のリリースを行うといったフローはなく、全体が完成してからのリリースであったため、やはりプロジェクトの完了が遠く、メンバーが疲弊した
前フェーズほど初期の計画から大きく進行がぶれることはありませんでしたが、前フェーズと同様に、リーダー負荷(属人性)が高く、メンバーも旧アプリケーションからの機能移植をし続けることに疲弊していました。
一方で、振り返りの導入により、毎週なにが起きたのか・どうすれば改善されるのか、ということを話す場ができたのは良かった点として挙げられます。 振り返りの場では、「コードレビューがなかなかされない」という課題に対して、「1つPull Requestを出したら2つコードレビューをする」という改善案を出す、といったことが話されました。 日々発生する小さな課題と簡単な解決法は議論されるようになったものの、抜本的な開発手法の改善はこのフェーズでは行われませんでした。 そもそも、「特定メンバーへの属人性」などの問題は、振り返りの場で取り上げられていませんでした。 プロジェクトのスケジュールが決まっていたため、「やり方を大きく変えずに完了までの障害を取り除く」ことにしか意識が向かなかったのかもしれません。
スクラム導入開始
サービスのリプレース作業が一段落し、定時バッチや管理ツールのリプレースをしつつサービスの保守を行うフェーズに移行しました。 このフェーズから、チームの人数は4人です。
スケジュールの決まっていた大きな案件が一段落し、自分たちの開発手法を見直す時間ができたため、チームはスクラムの導入を試みます。 スクラムがどのような開発手法なのかを短い文章で誤解なく伝えることは難しいため、敢えて説明しません。 スクラムガイドがもっとも正確で簡潔にまとまっている資料であるため、興味を持った方はそちらを読んでみることを強くお勧めします(リンク先に日本語訳のpdfがあります)。 この節では、私たちがなにを課題として捉え、なにを試して、なにが改善したのかをスクラムの知識がなくても分かるように記述します。
プロジェクト管理ツールとしては、RedmineにRedmine Backlogsというプラグインを導入しました。このプラグインは、スクラムに沿った開発を実現するための各種機能をRedmineに追加するものです。
このフェーズでは、開発メンバー4人だけでスクラムを導入しました。 理想的にはディレクターなどプロジェクトに関わる人間全員を巻き込むべきですが、まずは小さく始めたほうがよいと考えました。 プロダクトの責任者であるプロダクトオーナーの役割は、開発チームのリーダーである私を設定しました。
このフェーズでは、次のような取り組みを行いました。
プロダクトバックログの作成
プロダクトバックログとは、ざっくりいえば「実現したいこと」をリスト化したものです。 このリストは、必ず優先度順に並んでいる必要があり、要件の追加や変更に合わせて常に最新の状態に更新されている必要があります。 このリストは、書き方が決まっているわけではないのですが、私のチームでは「ユーザとして、人気の本のランキングを知りたい。なぜなら、次に読む本を選ぶための参考にしたいからだ」といった、誰が・何を・なぜ必要なのか、の情報を含んだユーザーストーリーという形式で記述しています。 プロダクトバックログに積まれたアイテムはプロダクトバックログアイテムと呼ばれますが、ここではイメージしやすいようにストーリーと呼びます。
前フェーズまではリーダーがチケットを作成して見積もりをつけ、一週間ごとの作業を区切り、メンバーはそのチケットを消化する、というフローで開発を進めていました。 このフェーズでも、開発案件の一次請けは開発リーダーであるという構造に変化はなかったため、基本的には今までチケットと呼んでいたものをストーリーとして再定義しただけで、その本質は大きく変わっていません。 ただし、見積もりの方法については大きく変化しました。
前フェーズまでの大きな課題は、見積もりでした。 リーダーが一人で見積もりを行うということは、見積もりという作業そのものに属人性があるということです。 また、メンバー全員が合意していない見積もりで開発を進めることは、チームが計画どおりに開発を進めるための大きな障害になると分かりました。 そのため、このフェーズからは、見積もりは必ず出社しているメンバー全員が揃っている場で行うようになりました。
見積もり方も、作業時間ではなくストーリーポイントと呼ばれる相対値で見積もるようになりました。 ストーリーポイントは、単位のない数字です。 たとえば、メンバーにとって基準にしやすい「作業A」を3として見積もったとします。 それと比較して、倍くらい手間のかかる作業は6と見積もります。逆に、手間が小さい作業であれば、1や2と見積もります。
見積もりに使う数字については、自由な数字ではなく、大きくなるほど間隔が広くなる数列から選択するようにしました。 私たちの場合、「1 2 3 5 8 13 21 ...」というフィボナッチ数列を用いています。 このような数列を使う理由は、大きな作業になるほど見積もりが不正確になるためです。 1時間でできる作業量は想像しやすいですが、1ヶ月かかる規模の作業はどれくらいの分量なのか正確に把握しにくいと思います。 大きな見積もりに細かい数字をつけるよりは、フィボナッチ数列のような大雑把な区切りをつけるほうがスムーズに見積もりができます。
さきほど「作業Aの倍くらいの作業は6と見積もる」という例を挙げましたが、私たちのチームではこの場合、前述の理由によりフィボナッチ数列に当てはめて数字を繰り上げ、実際には8と見積もります。
見積もりが直感的に行いやすくなる反面、大きな見積もりつけたストーリーは見積もりが不正確であるともいえます。私のチームでは、そのストーリーをより小さなストーリーに分割し、扱いやすい粒度にすることが多いです。
見積もりにかけるコストを下げることで、全体の作業規模の見積もりをすばやく行えることが相対見積もりを採用する理由のひとつです。 また、チーム開発を突き進めていくと実時間による見積もりではうまく見積もりにくいケースが発生します。 それについては、後のフェーズで説明します。
スプリントの再構築
前フェーズで行っていたスプリント(もどき)の運用を、正式にスクラムにおけるスプリントとして運用し直すことにしました。具体的には、次のことを行うようにしました。
- 次のスプリントにどのストーリーを積むか、といった計画をメンバー全員で行うようにした
- スプリントでどれくらいのストーリーポイントの作業がこなせるか(ベロシティと呼ぶ)を計測し、どうすれば生産性が上がるのか(あるいは、安定させられるのか)を議論するようになった
- スプリントの最後の振り返りで、計画に対してスプリントがうまくいったのか、どこを改善できるか、という議論が行われるようになった
-
毎日15分程度の立ちミーティング(デイリースクラムと呼ぶ)で、スプリントの作業は予定どおりに進んでいるか・今日はなにをやるのか・進行する上で障害はないか、などを確認するようになった
- 前フェーズでも毎日の立ちミーティングは行っていたが、漫然と「今なにをやっているか」を報告しあうだけの場になっていた
スクラム用語でいえば、スプリントプランニング(スプリントの計画)、デイリースクラム、スプリントレトロスペクティブ(スプリントの振り返り)が導入されました。 これにより、メンバー全員で計画を行い、計画を完遂するために協調し、次のスプリントに向けて改善を行う、というサイクルが回り始めました。 このことによる大きな成果は、リーダーの属人性が減り始めたことです。 この段階ではまだディレクターやサービスの運営担当者(以下、運営)との橋渡しとしてのリーダーの属人性がありましたが、チーム内の開発サイクルは、徐々にリーダーがいなくても回るようになっていきました。
また、一週間ごとに必ずゴールを設定し、そのゴールに対する計画もチーム全員で行うことになったため、チームの雰囲気は大きく変わりました。 感覚的な表現になりますが、PC/スマートフォン向けサイトのリプレースを行っていたフェーズのようなメンバーの疲弊感や閉塞感はなくなったと感じています。
かんばんの導入
プロダクトバックログに積まれたほとんどのストーリーは、作業として見ると粒度が大きいです。 たとえば、「ユーザとして、人気の本のランキングを知りたい」というストーリーで実現したいことが「Webに本のランキングページを作る」である場合、ランキングを表示するUIを作る・ランキングを生成するバッチを用意するといった作業が必要になります。 そのため、私のチームではストーリーを短時間で完遂できる粒度のタスクに分割することで、スプリント内の作業管理を行うことにしました。
タスクの管理には、Redmine Backlogsに含まれる「かんばん」というツールを使いました。開発手法の文脈上、「かんばん」という言葉にはさまざまな意味合いがありますが、ここでは単なるツールの名前を指しています。
このフェーズで導入したかんばんでは、各タスクについて「未着手」「進行中」「完了」という状態で進行状況を管理しました。各タスクでは、今だれがその作業を担当しているかが分かるように、担当者が設定できるようになっています。
かんばんは、視覚的に現在の進行状況を把握するために役立ちました。 かんばんのタスクを各メンバーがこなし、一日1回のデイリースプリントでかんばんの状況を確認するというサイクルで日々の開発は進められました。
また、ここでいうタスクは、徐々に実装作業だけではなく、「Aについてディレクターにヒアリングする」といった作業も含まれるようになっていきました。 チーム外の関係者とのコミュニケーションもタスクに落とし込むことで、必要な作業が明確化され、誰でもそのタスクに取りかかることができる状態になります。 このような取り組みを行うことで、関係者の橋渡しとしてのリーダー負荷も少しずつ減っていきました。
振り返りの方式変更
前フェーズまではKPTによる振り返りを行っていました。 しかし、Problem(問題点)とTry(新たに取り組みたいこと)を挙げることで改善点を洗い出すことはそれなりにできていたものの、Keep(良かったので継続したいこと)が挙がりにくく、KPTをうまく活用できていないという思いがありました。 私たちがKPTの進め方についての理解が浅かった部分もあったとは思いますが、このフェーズから、YWTという手法を試してみました。
YWTは、Y(やったこと)・W(わかったこと)・T(次にやること)を挙げて、改善サイクルを回す手法です。 Y(やったこと)・W(わかったこと)は事実を挙げていくだけなので、振り返りの敷居が低くなります。 わかったことから課題を見出し、最終的にはT(次にやること)を挙げることで改善に繋げるという点はKPTと同じです。 YWTは私達のチームにマッチしており、結果的により改善が行いやすくなりました。
スクラムを導入していなくても、振り返りを行っているチームは多いと思います。 振り返りがうまく機能していないと感じたら、やり方を変えてみることでうまくいくこともあるかもしれません。
開発作業の役割分担撤廃
私たちのチームは、アプリケーションコードは全員が触れる状態であったものの、インフラ作業は一部の担当者のみで行うようにしていました。 これは属人的な状態であるため、チームとしては「誰がどのタスクをやっても完遂できる」状態を目指したいと考えました。 そこで、このフェーズから、読書メーターチームはすべてのエンジニアにインフラ権限を与え、誰でも作業ができることを目指すようになりました。 幸いなことに、読書メーターは(ほぼ)フルAWSで構築したため、アプリケーションエンジニアでもインフラ作業に手がだしやすい状態でした。
当然、はじめのうちはインフラ作業に対する知見に差がありましたが、本番作業は必ず二人以上で行うというルールにしていたため、徐々に知見が共有されていきました。 もちろん、口頭での伝達だけでなく、資料化が甘かった部分については、随時資料を拡充していきました。
改善サイクル加速期
スクラムを導入して2ヶ月ほど経ちました。 新たな開発サイクルにも慣れ始めた頃、Regional Scrum Gathering Tokyo 2018というスクラムに関するカンファレンスに開発チーム全員で参加したことをきっかけに、チームの改善サイクルが加速し始めました。
このフェーズでは、毎週のように新たな取り組みが行われました。 スプリントが一週間と短かったため、「一週間でうまくいかなかったら次の一週間で別のやり方を試せばよい」という気持ちでいろいろなことを行いました。
項目ごとに、どのように変わっていたのかを紹介していきます。
エンジニア以外の関係者のスクラム参加
前フェーズまで開発メンバー4人のみでスクラムを行っていましたが、ディレクター、運営といったメンバーにもスプリントに参加してもらうようになりました。 それまでは私がプロダクトオーナーという役割を担っていましたが、ディレクターにスクラムの考え方を理解してもらいつつ、正式にプロダクトオーナーとして、スプリントの計画などに参加してもらうようにしました。
スクラムにおけるプロダクトオーナーは、「プロダクトの価値の最大化」に責任をもつ人間で、プロダクトバックログの管理が大きな役割の1つになると思います。 私たちのチームでは、次のようにプロダクトバックログを管理するようになりました。
-
ストーリーは、いつ、誰が、どのタイミングで作成してもよい
- プロダクトオーナー起因の案件に限らず、不具合改修やリファクタなど、必要だと感じたメンバーが随時ストーリーを作成する
-
作成された段階では、ストーリーはプロダクトバックログには積まない
- 「新規ストーリー」というグループでひとまとめにしておく
-
週に一度、プロダクトオーナーと開発メンバーでリファインメント(完了条件の明確化や見積もり、並べ替え)の時間をとり、プロダクトバックログを整理する
- 本来、この作業はいつやってもよいのだが、関係者を集めないと完了条件の明確化が難しいため、毎週決まった時間を抑えている
- 見積もりについては開発チームが責任をもつため、完了条件が明確になった後、開発チームだけで行うことが多い
ディレクター・運営がスプリントに参加することにより、ストーリーの完了条件を関係者全員がいる場で話し合うようになったため、認識の齟齬や手戻りが減りました。 前フェーズまでの問題点として、ディレクターと開発チームの橋渡しとしてのリーダーの属人性が高かったことを挙げましたが、このフェーズからそれが徐々に解消されていきました。
振り返りの付箋化
振り返りの進め方も、ホワイトボードにマーカーで書き出していくというやり方から、専用の小さなボードを用意しつつ、そこに付箋を貼っていく方式に変更しました。 付箋の大きなメリットは、貼り替えが可能な点です。 T(次にやること)に貼った付箋を、達成したらY(やったこと)に移す、といった操作がしやすくなったことで、より効率良く改善のサイクルを回すことができるようになりました。
私たちは毎週の振り返り後、T(次にやること)の付箋は貼ったままの状態にしています。 何週間か経って、Tの内容が意識せずとも実践できていると感じるようになったら、Y(やったこと)に移しています。 付箋の場合、Tとして挙げられたがなかなかYに移らないものは自然とボードに残り続けるので、自分たちがなにを意識できていないかを可視化しやすくなります。
また、専用のボードを用意したことで、YWTを毎日書きだして貼る習慣ができました。 もともと一週間に一度の振り返りとしてYWTを行っていたのですが、数日前に起きたことを思い出しながら挙げていくと、どうしても細部が欠けてしまいます。 日々の気づきを逃さないために、振り返りの付箋化は大きく貢献しました。
一日スプリントの導入
一週間のスプリントの作業を計画どおり完遂するためには、より小さな単位で計画を繰り返していく必要があることに気づきました。 そこで、一日単位を小さなスプリントと考え、その日の中で計画・実行・振り返りを行うようにしました。
一日スプリントを導入する上で、1つだけ問題がありました。弊社は裁量労働制を採用しているため、メンバーの出社時間がばらばらであったことです。 出社時間を揃えなければ、一日の計画や振り返りを行うことが難しくなります。 メンバーで話し合った結果、次のようなタイムスケジュールで、時間を合わせて仕事を行うようにしました。
時刻 | 内容 |
---|---|
13:45〜14:00 | デイリースクラム(一日の作業計画) |
14:00〜18:00 | 開発作業 |
18:00〜18:30 | 振り返り・再計画 |
合計、5時間程度(開発作業に絞ると4時間)は時間を合わせて作業していることになります。 このスケジュールにしたのは次の理由があります。
- チームで最効率を目指して全力で開発作業を行った場合、4時間を超えると過度に疲れが出るため
- 完遂すべきは一週間スプリントのゴールであるため、一日スプリントの計画がうまくいかなかったとしても上記の5時間以外の時間でリカバーできるようにするため
- 上記5時間以外の業務時間は、(基本的には)開発メンバーの自由学習時間とし、メンバーの技術力向上を促すため
一日スプリントの導入によって、「今日はどこまでやればよいか」が明確になり、心理的に余裕をもって開発を進めることができるようになりました。 一週間スプリントを計画的に進められるほか、計画が破綻しそうな場合はすぐに察知できるため、早い段階でスプリントの計画変更や中断について相談ができるようになりました。 また、計画・実行・振り返りのフィードバックループが毎日行われるようになったため、改善のサイクルがより効果的に回るようになりました。
曜日ごとのタスク管理
一日単位で計画を繰り返すうちに、一週間のうち何曜日に何をやる、という計画を管理できる仕組みの必要性を感じました。 前フェーズで示したかんばんは、「未着手」「進行中」「完了」といったタスクの状態は表せるものの、タスクにいつ取り掛かるか、といったスケジュールの情報は表すことができません。 Redmineではこのような要望をうまく満たすことができなかったため、より自由度の高いホワイトボードと付箋を使ってタスクを管理することに決めました。 まず、以下に示すように、横軸でタスクの状態を表すのではなく、曜日を表すようにしました。 これにより、何曜日にどの作業をしなければいけないかが一目瞭然になっていると思います。
タスクの状態は、ステッカーとマグネットで表すことにしました。 まず、すみっコぐらしのキャラクターマグネットを購入し、各キャラクターと開発メンバーを1:1対応させました。 このマグネットをタスクに貼り付けることで、そのタスクが進行中であることや、担当者が誰なのかがひと目で分かるようになりました。 また、完了したタスクにはシールを貼るようにしました。 これにより、かんばんで実現できていた機能はすべてホワイトボードでも実現できるようになりました。
この方式の導入により、タスクの計画や管理は飛躍的にやりやすくなりました。 私たちのスプリントは水曜日に始まりますが、水曜日の時点で一週間のタスクを洗い出し、次週の火曜日までの計画を考えるようすることで、安定してスプリントを完遂できるようになりました。 また、このやり方にすることで次のようなメリットもありました。
- 横軸が曜日のため、タスク管理だけでなくスケジュール管理として使えるようになり、このホワイトボードに「Aさん休み」や「BさんMTG」という付箋を貼ることで、チームメンバーの状況もわかりやすくなった
- 「追加で作成したタスクは青色」「障害のような突発案件は手のひら型の特殊付箋」といったように、タスクの種類ごとに付箋を使い分けることであとで振り返りやすくなった
- 曜日ごとにベロシティ(タスクの見積もりの合計値)を算出し、ホワイトボードに記載していくことによって、日々の作業効率を向上(もしくは安定)するための指標として利用しやすくなった
この方式は、メンロー・イノベーションズ社のやり方を参考にしました。 Joy, Inc.という本の中で紹介されています。 この本には組織づくりのさまざまな知見が詰まっているので、ぜひ読んでみてください。
1時間ごとの作業確認
一日スプリントの導入後、タスクは必ず一日以内に終わる粒度で作成するようになりましたが、作業時間内にタスクを完了できないことがたびたびありました。 対策として、「一日スプリントの半分の時間が経過したら、全体の80%のタスクが完了していることを確認しあう」というルールを取り入れてみました。しかし、感覚的に80%完了していても、コードレビューで発生する手戻りなどを含めると、想定以上に時間がかかることも多々ありました。
そこで、1時間ごとに必ず作業確認をする習慣をつけました。 一日の開発作業時間は4時間なので、計3回作業確認があることになります。 作業が想定よりも時間がかかった場合も、1時間の区切りで確認を行うことでリカバーしやすくなりました。
1時間の作業確認について改善を続けた結果、14時の段階で15時までにどのタスクをこなすかを計画し、15時にタスクボードの前に集合して、次の16時までの計画を行うといったサイクルに発展しました。 これは、要するに1時間の簡易スプリントを繰り返している状態です。 私たちのチームは、一週間のスプリントを完遂するために、1時間単位までスプリントを分割するようになったのです。
ペアプログラミング・モブプログラミングの活用
スクラムの導入と並行して、ペアプログラミング・モブプログラミングを少しずつ導入していきました。 ペアプログラミングとは、2人のエンジニアが1台のPCを使って開発を行う手法です。 参加者が3人以上になった場合、モブプログラミング(モブプロ)と呼びます。 かなりざっくりした説明ですが、私のチームではそれ以上に細かいルールを決めてやっているわけではありません。 この記事では両者を区別する必要がないため、複数人で行う開発作業をまとめてモブプロと表記します。
モブプロがチームにどのような変化を与えたのかを順を追って説明します。
開発における知見共有
はじめは、開発における知見共有の目的でモブプロを導入しました。 メンバー間の開発能力の差が小さくなることで、特定のメンバーへの属人性が減ります。 私たちのチームでは、特に属人性の高かったインフラ作業を中心に、モブプロ(この場合、モブ作業と呼ぶべきかもしれませんが)を採用していきました。
開発における知見共有と書きましたが、知見は「特定のライブラリの導入手順」といった資料化しやすいものだけではありません。 「コンソールの操作方法」「どんなことに気をつけて作業を行うか」など、開発パフォーマンスや作業の安全性に関わる小さなノウハウも含まれます。 すべての知見を資料化することは難しいため、このような小さなノウハウの共有は、モブプロが非常に適していると思います。
手戻りの減少
前述のとおり、私たちのチームは一日あるいは一時間の粒度で作業計画を立てていますが、その粒度で計画を行うと、コードレビューとそれによる手戻りが計画完遂の障害になることが多いことに気が付きました。
一人でコーディング作業を行い、他のメンバーがコードレビューを行うというフローでは、コードレビューで指摘された箇所を修正する作業が入った場合、想定した作業時間を超えることがあります。 コードレビューや修正にかかる時間をタスクの見積もりとして上乗せしてはいたものの、「小さなタイプミス修正」と「設計から見直し」は当然ながら同等ではなく、手戻り作業を一律バッファとして見込むのは難しいと分かりました。この手戻りを減らす手段として、実装作業にもモブプロを使うようになっていきました。
すべての実装作業をモブプロでやるようにしたわけではなく、手戻りが発生しやすい箇所、もしくは発生すると修正コストが大きい箇所を複数人で実装するようにしました。
たとえば、新たなREST APIを追加するケースを考えます。 エンドポイントの設計などは基本的にストーリーの完了条件定義の段階で行っていることが多いのですが、「永続化するデータのテーブル構造はどうするか」「内部のインタフェースはどうするのか」「クラスやモジュールの名付けはどうするのか」といった箇所はモブプロで実装します。 実装上議論の余地がなく、ほぼ迷わずに書けてしまうところまでできたら、残りは一人で実装するというケースが多いです。
最終的に小さなミスが発生することもあるので、最後にコードレビューも行っていますが、他のメンバーも設計や実装方針を一緒に行っている状態なので、コードレビューはかなりスムーズに行うことができます。
このように、モブプロ導入により、タスクのリードタイム(着手から完了までの時間)は安定するようになりました。 しかし、依然として見積もりの難しさは残りました。
見積もりに対する考え方の変化
モブプロ導入で手戻りは減りましたが、モブプロを前提とすると、タスクの見積もり方法が難しいことに気が付きました。 私のチームでは、ストーリーの見積もりについては相対見積もりを使っていましたが、タスクについては実時間による見積もりを使っていました。 タスクは必ず一日(4時間)以内で終わる粒度であり、相対見積もりを用いるよりも実時間を用いたほうが正確に見積もれると考えたためです。
しかし、モブプロを前提とすると、1時間と見積もった作業を二人でやった場合、どのように扱えばよいのか難しくなります。 単純に一人で作業した場合と比べて2倍の工数がかかったと捉えるべきでしょうか。 モブプロによって生産性が半分になったのかというと、そんなことはありません(生産性の定義にもよりますが)。
この問題は、「メンバー4人が2時間稼働できたら、8時間分のタスクが消化できる」といった人月計算の考え方が根底にあったため生まれたものでした。 一週間スプリントで相対見積もりをする際は、何人で作業するかは意識せずに、特定の作業より重いか軽いかだけで数字をつけていたにもかかわらず、一日スプリントのタスクを見積もる際は無意識に人月ベースの考え方で見積もっていたのです。
このことに気づいてから、タスクも相対見積もりで見積もるようになりました。 「作業Aに対して作業Bが何倍か」という考え方で見積もればよいだけなので、見積もりのタイミングでは何人で作業するかはあまり意識しません。 もちろん属人性が高い作業の場合、他メンバーへの知見共有も作業に内包され、実際に時間がかかったりするのですが、それは「チームとしては重い作業」ということで大きめの数字をつけます。 前述のとおり、大きめの数字を見積もりやすくするために、見積もりの値の候補はフィボナッチ数列です。 最初の見積もりが大きくても、知見共有により同様の作業の見積もりは次回より小さく正確になるはずです。
結局、チームの生産性という観点でみれば、どの作業を何人で何時間作業するかは本質的にはあまり重要ではありません。 決まったタイムボックスのなかでチームがどれくらいのベロシティ(見積もった数字の合計値)を出しているのか、この数字はもっと上げられる(安定させられる)のかを議論することで生産性を上げる(安定させる)ように努めればよいだけなのです。
もちろん、チームの半分以上のメンバーが休んだら流石にベロシティは下がるため、稼働人数が関係ないわけではありませんが、私のチームでは一人休んだくらいであればベロシティはほとんど変わりません。 逆に、そのくらいの状況でないとベロシティが安定せず、スプリント計画で約束したゴールを安定して完遂することが難しくなってしまいます。
私たちはモブプロを導入することにより、個人ではなくチームの生産性を正しく計測し、チームで計画を完遂するという考え方が、実感を伴った上で身に付きました。
新オフィス移行
トリスタでは、昨年オフィスの引っ越しがありました。 それに伴い、私たちのチームは新オフィスについていくつかの要望を出しました。 オフィス空間を再構築できる機会は多くないので参考にしづらいと思いますが、どのようにオフィスを構築するかはチームビルディングにおいて重要なことであるため、私たちのチームがどのようにオフィス空間を改善したのかを解説します。
壁一面ホワイトボード
オフィス移行前はタスクボードとして独立型のホワイトボードを使っていましたが、壁一面ホワイトボードにし、すぐ横に私たちのチームを配置してもらうよう要望を出しました。 その結果、タスクボードの幅が広くなり、依存関係のあるタスクを作業順に並べた場合などに全体像を把握しやすくなりました。 また、壁をタスクボードとして使うようになった結果、いままで使っていたホワイトボードが余ったため、そちらは開発作業の議論などに使うようになりました。 チームのすぐ横にいつでも使えるホワイトボードができたため、設計や議論のために会議室を抑えるということがなくなり、開発における不要な手間が削減されました。 コミュニケーション主体の開発を行う場合、自由に使えるホワイトボードの広さは作業効率の向上に大きく貢献すると思います。
パーティション撤去
チームメンバーの席の間に設置されたパーティションを撤去しました。 私たちの開発はコミュニケーション主体であるため、一人で黙々と作業する環境よりも、互いのモニタをすぐに確認して話しながら作業できるような環境を好んだためです。 パーティションがなくなったことでモブプロなどの複数人作業がやりやすくなったほか、小さなコミュニケーションの心理的障壁が下がり、常に確認や同期をとりながら作業がしやすくなったと思います。
モブプロスペースの導入
自席のすぐ横、壁面ホワイトボードの前に、小さなオープンミーティングスペースを設置してもらいました。 このスペースに40インチ以上のモニタを設置することで、頻繁にモブプロを行う環境ができました。 オフィス移行前も自席近くに同じようなスペースはあったのですが、さまざまなチームが使うスペースだったため、モブプロがしたいときにいつでもできる環境ではありませんでした。 また、自席の27インチモニタでは、複数人作業する際には若干のストレスがありました。 チームがいつでも使えるモブプロスペースができることで、モブプロはチームに一気に浸透していきました。
いつでも使える、と書きましたが、オフィス移行前に比べて利用者が相対的に少ないというだけで、上記のミーティングスペースは私たち以外が使うこともあるため、長時間の専有は憚られる場合もあります。 また、4人の開発メンバーだと、2人の共同作業を2箇所で行いたいこともあります。
最終的には、パーティションを撤廃したことにより確保できた自席スペースにも40インチ以上のモニタを設置し、モブプロスペースを確保しました。
このような環境になってから、モブプロを特別な作業と捉えることはほとんどなくなりました。 一人で実装作業中に他の人の意見が欲しくなれば他のメンバーに声をかけて即座にペアプロをしますし、作業が一段落して全体の進捗に余裕があるときに他のメンバーの作業を見に行って流れでペアプロ化、といったことが日常になりました。
ディレクターや運営と席が近くなった
トリスタでは開発チーム、ディレクターチーム、デザイナチームなど、役割ごとにそれぞれ席が分かれていました。 コミュニケーションコストを下げるためにはより席を近づけたほうがよいと考え、読書メーターに関しては、ディレクターチームと運営チームの席を隣り合った場所に配置してもらいました。 これにより、日常的なコミュニケーションの頻度が増え、業務上の細かい疑問などもすぐに話して解決できるようになりました。
また、スクラムイベント(スプリントの計画や振り返りなど)も会議室をとらず、自席近くのスペースで行うようになりました。 振り返り(YWT)の付箋やホワイトボードは自席近くに配置してありますし、自席の椅子をそのまま移動してサッとはじめられるようになったため、スムーズにスクラムイベントを進めることができるようになりました。
まとめ
本章では、読書メーター開発チームがどのようにチームを改善し、生産性を安定させ、属人性を排除したかを解説しました。 今回のような改善が私たちのチームでうまくいったのは、メンバー全員がチームの改善に意欲的であったこと、メンバーの人数がほどよく少なかったことなど、さまざまな要因が挙げられます。 前提条件が違うため、同じような手順を踏んでもうまくいかないかもしれません。 そもそも、チームとして目指す方向性が違えば、最終的なやり方も違ってくると思います。 属人性に関する考え方もチームが目指すゴールによって変わってくるでしょう。
また、うまくいった部分ばかりを述べましたが、いまだ課題は多いです。 改善を続ける過程で、課題がなくなることはありません。 直近は、他チームとの連携をよりよくするためにはどうすべきか、出社困難時のみ効率的にリモートワークを導入するにはどうすればよいか、などが大きめの課題として挙げられます。
本章で「こうやればうまくいく」という書き方ではなく、「このときにこれを試した」という時系列に沿った説明をしたのは、特定の方法ではなく改善のプロセスを追体験してもらいたかったためです。 小さな改善でも、繰り返していけば少しずつ理想のチームに近づくはずです。 みなさんのチームでも、ぜひいろいろなことを試してみてください。
Yo Ogino
サービス開発部部長