Gunosy Tech Lab の石川です。
この記事は Gunosy Advent Calendar 2022 の 8 日目の記事です。昨日の記事は今村さんの『EventBridgeとECSでお手軽バッチ処理基盤 (後編)』でした。
最近リモート環境でモブプログラミング開発をチームで行っているので、今回はそのベストプラクティスの一例に触れながら、どのように行い、どのような影響があったかを書きたいと思います。
概要
2020 年始めの COVID-19 の流行拡大以降、在宅勤務の導入が多くの企業に広まりました。Gunosy でも同年の 2 月頃から在宅勤務が導入され、現在でもスタンダードな働き方として継続しています。
そのような状況下で、大規模な既存システムのリニューアルのプロジェクトが発足しました。リリースがまだなので具体的な内容に触れることは出来ませんが、複雑なビジネスロジックと高い品質が求められるシステムです。技術領域も広いため当然チーム開発で取り組むのですが、我々のチームではモブプログラミングを利用して開発を進めることに決めました。モブプログラミングを行う理由や、その効果については後述します。
COVID-19 の流行拡大以降でリモートモブプログラミングに取り組む企業が増えている印象がありますが、改めてそのベストプラクティスの一例の紹介と、チームでの取り組みや課題について共有したいと思います。
モブプログラミングとは
モブプログラミングとは Woody Zuill によれば「同じ時間、同じ場所、同じコンピュータで同じものを」作り上げることのようです*1。実践的には、 3 人以上のメンバーが集まり、リソース効率よりフロー効率を重視し、複数の領域を開発者同士で補い合いながら開発する手法と言えます。
モブプログラミングではタイピストとモブという役割を順番に回しながら開発を進めていきます。タイピストはコードを書く役で、メンバーの中から 1 人だけが担います。モブとはタイピスト以外のメンバーを指します。モブは問題を議論し、解決策に合意し、タイピストに指示を出す役になります。
ちなみに Gunosy テックブログでも過去にいくつかモブプログラミングに関する記事が投稿されているのでぜひ参照してみてください。
モブプロ カテゴリーの記事一覧 - Gunosy Tech Blog
リモートモブプログラミングのベストプラクティスの一例
リモートでのモブプログラミングは Woody Zuill のモブプログラミングの定義とは矛盾しているように思われるかもしれません*2が、国内でも既にリモートモブプログラミングを実践していて、テックブログでその取り組みを共有している企業もありますし、国外にはそのノウハウを書籍にまとめて公開している*3企業もあります。また、その内容の抜粋がウェブ上に公開されています。
Remote Mob Programming | How we do Remote Mob Programming.
そこには、リモートモブプログラミングの成功のための要点が列挙されています。
- 全員がリモートで参加する
- 一部のメンバーがオンサイトで仕事すると情報格差が生まれてしまうため
- カメラは常にオンにする
- ノンバーバルコミュニケーションが重要であるため
- 定期的にオフラインで顔を合わせる
- 月イチでのオンサイトミーティングを推奨
- チームを小さくする
- 意見を言う機会を減らさないため
- 同じ時間を過ごす
- タイピストとモブの役割を果たす
- スクリーンシェアをする
- コラボレーション IDE (e.g. VSCode Live Share) よりも Zoom を推奨
- 10 分間のインターバルでタイピストを交代する
- 短い間隔でタイピストを交代することで集中力を保つため
- Git ブランチの受け渡しをスムーズにする
- 後述の mob コマンドの利用を推奨
また、同資料には次のような好影響があると紹介されています。
- チームでの議論の合意を下に開発が進む
- チームでの合意を下に技術的な決定やコードの実装を進めるため
- ADR (Architecture Decision Records) を利用して技術的決定を文書化を推奨
- 開発が一定の速度で進む
- コードレビューの待ち時間が減るため
- 難しい問題でも議論して問題を前に進めることができるため
- チームからの学びがある
- ナレッジの共有ができる
- いわゆる bus factor をチームのサイズにできる
- チームに信頼が生まれる
チームでの実践
チームとして実践する前に、まず原則としてモブプログラミングで開発に取り組む狙いを次のようにまとめました。
- スキルの共有と強い開発体制の構築
- 今回の開発は複数の境界をまたぎ、それぞれに高い専門性を求められるため、複数の異なる開発者の知識やスキルを共有したい。また、経験を皆で共有して、キーパーソンに頼らない強い開発体制を構築したい。
- フロー効率の向上
- 一時的にリソース効率は低下するが、これまでコミュニケーションコストとして発生していた、レビューや合意形成などの手間を減らし、モビングを通したメンバーのスキルの向上や、アイディア創出の促進、開発担当者の冗長化といったフロー効率を上げたい。
独自のルールや実践例
この原則を確認した上で、前述のベストプラクティスを取り込みながら、毎度のモビングセッションごとに振り返りと合意を下にしたルール化を通じて、自チームに合ったリモートモブプログラミングのやり方を模索しました。
以下に自チームで合意したルールや実践例をいくつか列挙します。
- COVID-19 の流行状況やメンバーの居住地の点から年に数回だけ不定期にオンサイトで仕事した
- タスクを兼任するメンバーも多かったので 5 ~ 6 人がコアメンバーとして参加した
- 業務の関係上、中座や途中参加、 ROM での参加を許容した
- タイピストがアイデアの提案としてコードを変更してもよいとした
- Google Calendar との連携のために Google Meet を利用して画面共有をした
- 15 分ごとにタイピストを交代することにした*4
- 設計の議論やレトロスペクティブに miro を活用した
- モブで行うほどではないタスクは個人タスクとして切り分けて消化した
- モビングインターバルが 4 回終わるごとに 15 分程度の休憩を挟むことにした
- ただし、モブの参加人数に応じて休憩の頻度を変更する
- モビング中の飲食は OK (モビングは疲れやすいため休憩時のおやつを推奨)
- モビングセッションの終了の 20 分前になったら 1 日の作業の振り返りを始めることにした
mob コマンド
mob コマンドの活用はスムーズなモブプログラミング開発に不可欠なツールでした。
mob コマンドは前述の書籍を執筆したチームが開発した、リモートでモブプログラミングを行う際の Git ブランチの受け渡しをスムーズに行うためのツールです。
ここでは主な mob コマンドについて紹介します。
- start
- mob ブランチへチェックアウトしてタイピストを開始する*5
- next
- タイピストを終了して mob ブランチの変更をプッシュする*6
- done
- mob ブランチの全変更を squash して base ブランチに戻る*7
以上のコマンドを利用して、以下の要領で開発を進めていきます。
- タイピストが画面共有をしてから
mob start
を打つ - タイピストの番が終了したら
mob next
を打つ- 画面共有を続けて
mob next
の実行が成功するのを見せる
- 画面共有を続けて
- 次のタイピストが画面共有をしてから
mob start
を打つ - 機能開発が終了するまで 2 ~ 3 を繰り返す
- 機能開発が終了したら
mob done
を打ち、コミットしてプッシュする
このようにして、モブに参加するメンバーが共通の作業ブランチに触りながら、効率よくブランチを最新の状態に反映した上で受け渡していくことができます。
また、 mob コマンドでは環境変数を変更してプロジェクトごとに設定をカスタマイズすることも可能です。例えば、MOB_NOTIFY_COMMAND
という設定でタイピストの終了時間をトリガーに起動するコマンドを設定できます。我々のチームでは Slack API をコールするスクリプトを設定し、タイピストの終了時間になると Slack のチームチャンネルに通知メッセージがポストされるように変更しました。
課題
チーム内ではリモートモブプログラミングの恩恵を強く感じている一方で、課題もいくつかありました。
- モビングセッションによるスケジュールのブロックが強く、開発リソースがかなりの割合取られてしまった
- プロジェクトチーム以外のチームメンバー(いくつかの部署から数人が今回のプロジェクトに参加していた)にモブプログラミングのワイワイした雰囲気を外から見て孤独感を覚える人もいた
まとめ
以上、リモート環境でのモブプログラミングについてそのベストプラクティスの一例や我々のチームでの取り組みについて紹介しました。
個人的には、今回のプロジェクトの開始時点では育休中だったため途中からの参加となり、当初はモブプログラミングの開発体制に合わない感覚があった記憶があります。しかし、プロジェクトとモブプログラミングに慣れるにつれてそのメリットが理解でき、徐々に自分自身の成長やプロジェクトの成熟を感じることができるようになりました。
今回取り組んでいるサービスはまだリリースされていないので、品質や運用にどれほど良い影響が与えられているかの検証はこれからになります。本記事がリモートモブプログラミング開発を検討する際の一助になれば幸いです。
次回は koizumi さんの『Snyk IaC + Reviewdog + aqua ではじめるDevSecOps』です。
*1:https://mobprogramming.org/
*2:「同じ場所、同じコンピュータで」という点で
*3:https://leanpub.com/remotemobprogramming
*4:https://timer.mob.sh/ を利用した
*5:チェックアウト前に fetch と merge でリモートブランチに状態を合わせるコマンドが打たれる
*6:プッシュ前に add –all と commit する。mob config で設定した MOB_WIP_COMMIT_MESSAGE がコミットメッセージに使われる
*7:mob ブランチはローカルとリモートの両方から削除される
*8:https://github.com/remotemobprogramming/mob/blob/main/diagram.svg より転載