👨‍👩‍👧

リモートモブプログラミングを9ヶ月間やってきたので振り返ってみる

2020/12/20に公開2

はじめに

今年もそろそろ終わりなので、振り返りながら記事をまとめています。
今年の個人的なトピックとしては

  1. 職場が変わったこと
  2. 初めてのマイクロサービスでの開発
  3. リモートワークになったこと

が大きいところです。
特に最後のリモートワークについては、大きな変化であったもののなんとか対応ができたと思っています。
過去のプロジェクトの経験では複数拠点・複数チームに跨ってmonorepoで開発したことがありましたが、今回の各チームメンバー一人ひとりが遠隔地にいる状態での完全リモートは今回が初めてでした。
その当時は各拠点にチームリーダーがいて、merge作業するのにも大号令でテストが壊れる度にチーム間で軋轢が生まれていくという自体が発生し、だんだんその歪からコミュニケーションもコストが増えていった苦い思い出がありました。

リモートワークが始まる前の状況

今年1月にJoinしたチームはレセプト業務の開発担当しているチームでした。
マイクロサービスで開発している1チームになりますが、他にも3つの開発チーム、QAチームがいる状況でした。
ドメイン知識がゼロからのスタートでしたが、幸いなことにこのチームでは開発作業自体はモブプログラミング形式(以下モブ)で進めており都度、業務内容の確認や開発をすすめる上で必要になるテクニカルな要素のフィードバックを受けることができ比較的に早く立ち上がることができたかと思います。

モブプログラミングについては以下のスライドが参考になります。

リモートワークの開始〜チーム再編成へ

2月初旬ぐらいでしょうか。コロナの報道も大きくなり、在宅勤務のテストトライが始まったのが。。
1週間ぐらいテストしたのですが、「いけるのでは?」という実感は得られました。
これは上述しているモブ形式の開発スタイルをとっていたというのが大きかったです。
その当時は自分も入れて4名体制でしたが、同じ一つのディスプレイ[1]をメンバーで見る感じではなく、モブのドライバーとなる人の画面をzoomで共有していました。zoomの画面共有越しにあれこれと話しながら開発するスタイルでした。
リモートでは相手の生な声と顔は見れませんが、コーディング等の開発は元々ネット越しであった為ほとんど違和感なく進められるというのもありました。
3月から本格的にリモートワークが全面解禁?となり1ヶ月ぐらいしてチーム編成が入り暖簾分けしたチームのリーダーとしてやっていくことになりました。メンバーが減って2名体制になりましたが6月に新人の @yknoguchi がJoinしてくれてましたが、3月以降もずっとモブ形式の開発スタイルを継続していきました。

リモート・モブのメリット

9ヶ月以上に渡りリモート且つモブ形式という開発スタイルでやってきましたが、振り返ってみてよかったことをまとめていきます。

1. 適度な集中

リモートワークだ本当に一人でモクモクと作業をすると人によりけりですが集中が続かなかったり、逆に集中しすぎて燃え尽きてしまうことが出てきます。[2]
モブは時間を区切ってドライバー[3]とナビゲーター[4]が入れ替わる仕組みをとっていて、それが適度に集中を高めてくれます。
いわゆるポモドーロ・テクニックですね。
自分は意思が弱いのでリモートで完全に一人だったら仕事以外の誘惑に負けていたかと思いますw

2. 孤独からの開放

他のチームメンバーと会話していると聞くのが、やはり孤独で辛いというのが多かったです。
常時テレビ会議をつなげていますので、その場でリアルタイムでコミュニケーションしながら進められるのがいいです。
個人的には開発作業は基本孤独だと思っているのですが、それがモブであーだこーだ言いながら進められるのは目からウロコでした。

3. コミュニケーション・オーバーヘッド低減

リモートだと要件だったり仕様を説明するのに、資料を起こしたりSlack等のチャットでフォローをしたりコミュニケーションはそれなりに意識を使います。特にチャットとかでは質問のラリーが発生しがちです。
微妙なニュアンスだったり情報格差による漏れがないか?とか気遣うことが結構多く、ドキュメントを作りすぎたり、足りなかった分を後から別途説明するなど過去のプロジェクトでは行ってきました。
それがモブではリアルタイムで都度状況共有して、チーム内なら誰もが一通り知っている[5]状況を作ることがリモートでもそこまで難しくなく出来ると思います。
メンバーの理解の状況を常に会話で確認し、都度フォローします。また込み入った概念や仕様については、その都度ドキュメントの作成するしないも合意をとり、必要であれば、その場でみんなでesaに書きなぐるなどしました。ドキュメントも作りすぎず、いい塩梅にすることができたと思います。
オーバーヘッドが減るというのは、コミュニケーションにかかるコストが減るということではなく、常に小さくコミュニケーションを行う(=コストをかけ続ける)ことで前後で余分なコストを払わなくていいようにするという意味です。
Just In Timeでコミュニケーションすることで最適化され、レスポンスが良くなる感じでしょうか?

4. pull requestレビューがゼロタイム

まったくのゼロというのはアレですが、小規模なものや中規模程度まででブランチの生存期間が短いものであればPR作成してCIが通ればすぐにmerge可能な状態になります。
コーディングで常にレビューを受けながら進められている状態なので、基本的にレビューによる手戻りが発生することはありません。
これはレビューされる側、する側にも心理的負担が少なくて良いと感じています。
レビューも一つのコミュニケーションだと思っているので上述したオーバーヘッド。。どうしてこういう指摘が入ったんだろう?指摘内容がキツすぎないかな?とか余分なコミュニケーションコストが発生しがちなのですが、そういったことはありません。
またありがちなのが、PRレビューが追いつかず期間が空いてしまうことでConflictが発生したり、コンテキストスイッチの追加コストも発生しがちです。ちょくちょく自分がブロッカーになってしまい心理的な負担を感じていた時があったのですが、今はそれがありません。
副次的な効果だと思いますが、レビューに時間をかけて品質を良くしていこうという考えはなく、レビューは常に行っているので、どういう設計やプロセスだったら品質を上げれるのだろう?というのにフォーカスが出来るようになった様に思います。

5. 知識共有・学習機会を得ることができる

自分自身や新メンバーがチームにJoinして感じたことですが、知識共有と学習機会を得ることには良いアプローチなのでは?と思いました。
まず一番最初に躓く環境構築のセットアップからもモブで始めていきます。モブの雰囲気を掴んでもらいつつ、ドメイン用語も実際の会話のなかで現れるので、都度説明を行いアプリケーションのコードにも触れていってもらいます。
最初は当たり前ですが、業務知識やテクニカル面で躓きますが、その都度フォローを貰えるので徐々に理解が深まっていきます。
結果としては受け入れがスムーズにでき、立ち上がりが早くできたと思います。
6月に配属された @yknoguchi ですが、学生時代や研修時に使ったプログラミング言語とは今のチームの開発言語は違ったりしますがリモートという中でも、5ヶ月目から一機能の開発のリード[6] を要件定義からリリースまで任せられるレベルになりました。

モブでは毎日が全て学習機会だと思っています。
エディタの使い方一つとっても学びがありますし、言語化が難しいテスト手法や設計原理なども書籍で学ぶよりもリアルで理解が進みます。毎日同じことをやっている様でもプロジェクトの成熟度が上がったり、メンバーが新しい取り組みをしたら、それが新しい知識としてチーム内に浸透していきます。
チームメンバーでそれぞれ得手不得手があり、みんな違うのと基本皆好奇心旺盛で新しい取り組みをしてくるので日々気づきがあります。

モブではスペシャリストは育たないかもですが、ゼネラリストがいい感じに育つと思っています。

改善してきたこと・意識してきたこと

リモートでモブをするのに、常により良い開発体験にしていきたいと思っています。
ただまだ手探りな部分が多く、再現性がある有益なプラクティスにまでは昇華することは出来ていません。
チームによって変わってくるものだと思っていますが、現チーム内で意識してきたこと・改善してきたことを紹介したいと思います。

雑談Welcome

今まで会社に来て業務外の雑談していたのが、リモートワークになってからそういう機会はなくなってしまったのではないでしょうか?
現チームではモブの開始時、昼休憩を挟んで再開時に積極的に雑談タイムを設けています。会話の内容は本当に多岐に渡り、趣味や身近な出来事だったり、ニュースや面白ネタなどもtwitterや社内Slackからもピックアップして雑談しています。
モブではドライバーとナビゲーターがコーディング等を実況しならがら進めます。会話がコミュニケーションの中心になるので、気負いなく合いの手を入れる場の雰囲気・・マインドが必要になります。
コーディングミスに気づいた場合にすぐにツッコミを入れたり、仕様等について理解が追いついていかなかったら恐れずに質問をしたり、場合によっては議論を行うことも必要になってきます。
ドライバーが順番に回ってきて手が止まったり、やることが迷子にならない様にナビゲーターの役割がかなり重要になります。
ドライバーも手を動かしながら、思考していることを垂れ流しして不安と感じていることなども発信してナビゲーターにフォローを貰います。
モブの理想としては、相手を信頼して適切に情報を発信して細かくフィードバックを貰うことです。
チームにJoinして最初のモブではなかなか分からないことだらけで難しいことだらけだと思います。
その中で自分の得手不得手や知識バックグラウンド、色々な物の考え方等を自己開示することに不安を覚えることもありますが、いきなりモブの中で発信していくのはハードルが高いです。
雑談であれば自分の趣味趣向とかも発信しやすいですし、些細な話題とかからでも人柄とかも感じ取れるので良いです。雑談が気軽にできる雰囲気がモブでの発言をする心理的なハードルも下げることになります。心理学的にも相手を知ることや自分を知ってもらうことで、信頼関係がお互いに生まれフォローを積極的に行えることにも繋がります。

あと雑談は単純にアイスブレイクの意味もあります。モブをやっていると結構集中力を使いすぎてしまうことがあるのでリセットさせます。頭をリセットしてスッキリして次のターンのモブを開始させます。

空中戦になりやすい議論のアウトプット

込み入った議論をする上で全て口頭で済ましてしまうと、認識の齟齬や取り残されるメンバーが出てきたり、後で振り返ることが出来なくなってしまいます。
社内共有システムとして esa を使っているのでなるべくそちらに議案を文書化して残すように意識しました。最終実装フェーズになったらGitHubのPRやIssueにesaのリンクを残して振り返られる状態にしていきます。
文章化は大事なのですが、どうしても図に起こした方がいいものもあります。完全リモートなのでリアルホワイトボードを皆で書き殴るということができないので、悩ましいです。
そこで PlantUML で各種図を書く様にしました。
幸いなことにesaにPlantUMLのDSLをそのまま貼り付けることでイメージ化されますし、DSL内のテキストはesaの検索対象になるので相性は大変良いです。
シーケンス図やクラス図といった代表的なUMLダイアグラムは以外でもワイヤーフレームやマインドマップとかもPlantUMLをモブでディスカッションしながら書き殴る様にしてきました。
PlantUMLはゆるく書くことができるので、最初どう書いていくのが良いかチーム内で議論しながら図をまとめていきました。一つ図をまとめることができると、書き方の知見が溜まって表現の統一もできました。次に新しい図を書く時も以前のフォーマットを合わせることで、だんだんスピーディに書けるようになってきました。
シーケンス図やコンポーネント図などはコピペしてas-is, to-beとして残せて、チーム内で統一したイメージとして定着できるようになりました。
PlantUMLはテキストベースなのでドメイン用語とアプリケーション内の論理名はマッピングする様に意識的に書く様にしていきました。

他チームとの連携をスムーズにする

マイクロサービスで開発していて関心事が別れているので、基本的にはメインの関心事のみに集中できていいのですが、他チームとの連携が出来ていないとシステム全体として安定した開発ができまん。
連携仕様となるドキュメントの共有やレビューといったのもについては、チーム全体で常に改善がされていっていっていますが[7]、それでもドキュメントベースだけでは済むことはありません。
Slackチャットで問い合わせを受けてやり取りすることもありますが、やはりラリーが発生しがちです。
あとモブをやっていると集中しすぎてSlackに気づかないということがあります。
チームチャネルにモブ中のzoomのリンクを貼っておき、いつでも他のメンバーが割り込んで話かけてもOKだということを宣言しています。
割り込みになりますが、なんどもチャットでラリーするよりもいいですし、リアルだと普通にできていた話しかけが出来ない・されないというのもお互いストレスになると思うので許容しています。

モブをやってないチームもあるので、理解してもらうというのも重要ですが。。

開発者体験の向上を大事にする

モブでやっていて、毎回同じ繰り返し作業をしていて効率が悪いとチーム全体のパフォーマンスへの影響が大きいです。というかスマートに開発したいじゃないですか、特に他のメンバーの目もあるのでw
レビューもあまり細かいことばかりを指摘しても嬉しくないし、コード整形やLintとかはツールでカバーできるものはなるべくそちらに任せたいという思いがあります。
先に記述したモブとしてメリットとして知識共有・学習の面があるので、いいものがあれば積極的に取り込んでいきたいです。
具体的な取り組みとしてパッケージ自動アップデートやLintの導入だったり先日紹介した カバレッジの可視化 等なメジャーなものからプロジェクト固有で使用していないAPIを洗い出しするツールの作成など多数あります。
スペースの都合で全部を紹介することはできないですが、今回はモブの進行をスムーズにする為に作ったbotを紹介しておきます。

https://github.com/k2tzumi/mob-timer-bot

Slackと連携するモブ用のタイマーアプリになります。
リンク先に動作イメージも貼っているので、大体イメージがつかめると思います。

支えになっている要素・背景

モブを導入してチームを運営をしていますが、プロダクトや組織の環境によって支えられている(=ないと厳しい)と感じているものを触れておきたいと思います。

20%ルール

業務時間の20%を使って、個人の関心事に注力して活動を行って良いというルールがあります。
ずっとモブをし続けてしまうと、緊張感を強いられすぎて辛いので個人活動の時間は必要です。
モブでやった所で躓いた所を整理する時間だったり、直接的な機能ではないもののプロジェクトの改善を行う時間に充ててたりします。
自分は上記に書いた開発者体験を向上させる為に良く使っています。

また技術検証で、チーム内に知見がないものは個人活動で試行回数を増やしてスパイクを行います。
研究開発とかはあまりモブにはマッチしないと思っています。
あと単純作業とかは個人活動で進めた方が早いものは、モブでやらないほうがいいです。
単純作業を無くすために20%ルールをうまく活用していきたいというのもあります。

マイクロサービス(DDD開発)

モブのチームとしては少人数でないと成り立たない[8]と思います。
チームの人数が多すぎると発言しない人が出てきたり、集中力が分散しがちになりミスを見逃したり、意見を集約させるのにコストが出てきます。
チームのスケールを大きくさせると破綻するので、適切に関心事を分離してチーム分割してプロダクトも発展させていくマイクロサービス開発でないとマッチしないと思います。
逆にマイクロサービス故に関心事を特定の人に依存させることになるので、一人が抜けて破綻することが無いようにする為にモブという手法を取るのは理にかなっている気がします。
特に業務が複雑で品質の要件が厳しく、多くの目が必要とする開発にはマッチすると思います。[9]
逆に集中できる環境がないと生産性は上げづらい側面があるとも思います。

最後に

@yknoguchi がモブの体験記事をアップしてくれました。
https://qiita.com/yknoguchi/items/2dc2888c5e3853271534

モブのメリットだけでなく、モブの難しさという点も言及してくれたのでアンサー記事になれば嬉しいです。

モブに限りませんが、ドメイン用語や業務知識を丁寧に理解をしてもらうには繰り返し復習が必要ですし、チームに慣れすぎてしまっているメンバーが暗黙知とは意識せずに会話してしまっていたこともありました。
メンバーの理解度を把握せずに進めてしまって、手が止まるケースがあったことはあまり良くないことですし、まとめで触れられている通りコミュニケーションをもっと増やすべきで、受け入れ側がもっと丁寧にフォローする必要がありました。
扱っている業務が複雑だったり、未経験のテクニカル要素が多かったのでインプットの総量が多すぎて消化不良のままになってしまっていた問題については、モブだけでなく個人で整理・復習する時間を別途設けると良いと思いました。

ナビゲーターの指示をこなすだけで何となくドライバーが出来てしまうのは、チームJoin直後に自分自身も経験がありました。そこをうまくフォローできなくて申し訳なかったです。
何度か繰り返しやっていくにつれて理解が進んでいきますが、そこまではなんとなく達成感がなく不安を覚えてしまいます。早く理解するには自分がナビゲーターの時に積極的に指示を出すことが大事です。次のドライバーの番が回ってくるので、やることを先回りする様に意識することが私個人の経験としては良かったです。勿論ドライバーの時に理解ができるまで手を止めて聞くことが大事です。ただやっぱり勇気が必要になりますし、そこもフォローが必要でした。

「ずっとチームの会話に入らない人がいる」よりも「一時的に議論が止まっても、チーム全体で内容が理解できている」方が圧倒的に得です。

色々苦労をしたなかで本質を見抜いてくれていて感動しましたが、まさにこれでモブを成功させる上で重要な点です。
ただこれを理解するのに実際やってみないと分からない。。というのは言い訳でしかなく、ちゃんとチームJoinした際にモブというスタイルを選択した理由と目的というのをちゃんと伝えるべきだと思いました。

今回の記事を書こうと思った理由が、なんとなくモブのスタイルを踏襲してきて明文化できていなかったのをまとめたいという気持ちからです。

色々書き殴ってしまって綺麗にまとめられていませんが、また新しいメンバーが増えたら今回の記事も踏襲して説明していきたいと思います。

明日は @yusukefushiki が投稿してくれるみたいなので、よかったら覗いてあげてください。

脚注
  1. 若しくはプロジェクターを映し出すなどして ↩︎

  2. リモートの経験がない方でも一人プロジェクトだと想像してみてください ↩︎

  3. コーディングをすすめる人 ↩︎

  4. ドライバーに支持をする人 ↩︎

  5. 完全に理解していなくても、大まかな背景だったり最低限必要な情報に辿り着ける ↩︎

  6. チーム内には20%ルールという制度があるのですが、自分で好きな開発ができます。個人活動として運用改善周りの機能実装を主体的に進めてもらいました。他のチームメンバーはレビューしますが、手取り足取りでフォローまではしません。 ↩︎

  7. apiDocやデータベーススキーマなどマイクロサービスで情報分散しがちですが、情報を一元的に参照できる環境を構築するなど ↩︎

  8. 個人的な感覚だと3-4人が妥当 ↩︎

  9. レセプト担当していますが、勘定系とかは良さそう。心理的安全性も担保できる ↩︎

Discussion

nakaj1manakaj1ma

mob-timer-botを使ってみようと思ったのですが、READMEのリンクで開けないところがあってそこから進めません。一応issueをあげてます

katzumikatzumi

ありがとうございます。
OAuthの設定周りの所ですねー。
ちょっと雑にドキュメントをまとめてしまっていたのでわかりづらくて申し訳ございません。
GASをdeployしてウェブ アプリケーションとして登録して発行されたURLをSlackに連携する流れになります。
URLは例で書いたものなので、アクセスできません。

GASのデプロイダイアログ

ロケールが英語ですみませんが、こんな感じのデプロイダイアログに表示されるURLが正しいものとなります。
環境毎にユニークなURLになるのでその様な例にしていました。逆にわかりづらくしてしまったようで申し訳ないです mm

せっかくなのでもう少し説明させていただくと Slack APIのページCreate New App から適当なアプリケーション名をつけてアプリケーションを登録します。登録後にアプリケーションのクレデンシャル情報が確認できますので Client ID 等を控えてGASのプロパティに設定してください。設定するプロパティ名とその設定内容はドキュメントにある通りです。
プロパティ設定とdeploy自体が済んでいれば上記URLにアクセスしてもられば、その画面にRedirectUri が表示されるはずです。

OAuth認証画面

こんな画面が表示されれば、GAS側は対応が完了です。

上記のURLがOAuthのリダイレクトURLとなり、今度は先に登録したSlackアプリケーションのOAuth設定をしていく流れとなります。
OAuth設定時にそのURLを登録して、ドキュメントに記載しているscopeの権限を付与してください。
そこまで終われば実際にOAuth認証ができる様になっていますので、Authorize. リンクから認証を終わらせてください。
後はbotを動かす為の以下の設定が必要です。

  • モブを開始するスラッシュコマンドの登録(Slash Commands)
    スラッシュコマンドの名前を登録してください
  • メッセージ・アクションを行う為の設定(Interactivity & Shortcuts)
    Request URL にGASのウェブアプリケーションのURLを登録してくさい

OAuthの認証完了画面にリンクを付けていますので、そこから辿れると思います。

ざっくりとした説明としては以上になります。

全般的に手順が分かりづらい部分があったり、手順が漏れている(nodeモジュールのインストールとか)箇所がありましたので、ドキュメントを見直してみたいと思います。