👬

【半同期的ペアレビュー】ペアレビューは同期的でなくてもよくないですか?

2023/05/26に公開

半同期的ペアレビューは筆者の造語です。

TL;DR

半同期的ペアレビューとは・・・

  • 同期的に集まってレビューする
  • PRにチェックポイントを作り、そのチェックポイントまでは非同期的にレビューする、チェックポイントだけ同期する
  • 何事もなくチェックポイントに到達した場合は、到達した旨を伝え、全員到達したら次のチェックポイントに向かう
  • 非同期的なレビュー中は、疑問点や指摘点などが出次第発言し、同期的に解決する

前提条件

ペアレビューが有効な場面。
Pull Request(PR)に2人以上のレビュワーが必要な場面。

背景

PRのマージに2人以上のコードレビューが必要な開発現場です。
特に集まらずバラバラにレビューすることを非同期レビューとしましょう。簡単なレビューであればこれでよいでしょう。
難しいPRに対しては、ペアレビューすることが有効です。集まってレビューするので「同期的」にレビューを行います。「同期的ペアレビュー」と呼ぶことにします。
同期的にペアレビューするといいこともある反面、理解の速度や仕方は人それぞれなので、同期的にしすぎると逆に速度や精度が落ちることもあります。
そこである程度ペアレビューに非同期的な要素を取り入れることで問題を解決するのが「半同期的ペアレビュー」です。
実際に筆者の所属する開発チームに半同期的ペアレビューを取り入れてみて好評だったため、記事にまとめることにしました。

各レビュー方法について

非同期レビュー

PRが出されても、多くの場合は各レビュワーが好きなタイミングで特に集まらずにレビューをするでしょう。簡単なPRである場合は時間を揃えて集まるよりも独力で見た方が効率がよいことがほとんどです。
今回はこのようなレビュー方法を、時間を揃えず非同期的に行うことから、非同期レビューと表現します。

非同期レビューは、以下のような特徴があります。

  • 自分の時間でできる
  • 自分のペースでPRを読める
  • 自分の詳しくない範囲の質問はすぐにはできない
  • 総じて簡単めなPR向け

ペアレビュー

簡単なPRは非同期レビューで済むことがほとんどですが、開発現場では時折(仕様上/実装上などで)難しいPRも出されることがあります。難しいPRでは、よくペアレビューが用いられます。ペアレビューとは、2人のレビュワーで時間を合わせて集まり、一緒にコードレビューを行うものです。
集まってレビューをすることで、片方が仕様面に詳しくなくてももう片方がすぐ補える、片方がすぐにコードリーディングを終えてもう片方が説明できる、などお互い能力を補い合い質のいいレビューを高速に提供できることが期待できます。
また、難しいPRのレビューはモチベーションが湧かないものです。「2人で時間を合わせる」ことで、強制的にレビューの時間を作れることも特徴の一つです。これは時間を埋めることと、もう1人のレビュワーの監視の目によるものがあります。

  • 時間を揃えて、集まってレビューを開始する
  • レビュワー同士の能力を補完することで、高速に質のいいレビューを行う
    • 自分の分からない知識も、すぐに質問できる
  • 時間を埋めるため、強制的にレビューに入ることができる
  • 総じて難しめなPR向け

同期的ペアレビュー

さて、ここでペアレビューの行い方が問題になります。

レビューの行い方は、基本的には以下のような流れで行うと思います。
人によって違いはあると思いますが、順番についてはこの記事の本質に関係しないので、以降説明のためにこの流れに沿って説明します。

  • PRのメッセージを読む
    • PRの概要を読む
    • PRの動作確認を読み、実行する
  • コードを読みながらレビューコメントをつける
    • コミットXを読む
    • コミットYを読む
    • コミットZを読む

ペアレビューをする上で、PRの概要や読むコードの箇所を逐一同期することが多いように感じます。レビュワーの片方が概要文を音読し、それをもう片方が聞く、といったペースで進みます。今回はこれを同期的ペアレビューと呼びましょう。

実際に逐一同期する場合のレビュー風景を、「PRの概要を読む」段階で想像してみます。

Aさん「時間なったのでペアレビューしましょう。まずは概要から読みましょう」
Bさん「OK」
Aさん「このPRでは、まずはXXをXXXXしたとのことです(これは簡単だわ)」
Bさん「(これは簡単だわ)」
Aさん「で、次にYYYYYYのような背景があったとのことです(この背景知らないな、後で深掘りしよ)」
Bさん「(あーこの話ね、知ってる知ってる)」
Aさん「最後にZZをZZZしたとのことです(これ何?むず)」
Bさん「(ここは難しいな)このZZZZしたってどういう意味なんでしょうか?」
Aさん「ではZZZZについて考えてみますか・・・」

このように同期的に進めると、理解のペースを揃えられるようにも一見見えますが、簡単な内容も同期的に読んでしまう、難しい内容に入った際にうまく止める必要がある・・・などの改善点が見えてきます。

ここでは「PRの概要を読む」風景で例示しましたが、特にコードを読む際は顕著に改善点が現れます。概要文の読み方であれば基本は前から読めばよいのですが、コードの理解の仕方は人によって大きく違い、読む順番も違えば読む速度も箇所によって変わります。ある部分はAさんのが先に読めるが、またある部分はBさんのが先に読める・・・といった具合です。ここを同期しすぎるとお互いの理解の妨げになってしまう部分が多く出てしまいます。

ところで、「お互いの理解のペースを合わせられる」ことをメリットできる場合もあり、「真に慎重に見なければいけないPR」を見るのであれば、レビュワー同士で足並み揃えた方が確実でしょう。

まとめると、同期的ペアレビューは以下のような点が見えてきます。

  • PRメッセージやコードなどを、レビュワー間で同期して同じ箇所を見るレビュー方法
  • お互いの理解のペースを合わせられる
  • 自分のペースでレビューをすることが難しくなる
  • 簡単な内容でも同期してしまう
  • コードの読み方は人それぞれなので、人の読み方に合わせることで理解がしづらくなる可能性がある

ペアレビューの改善案: 半同期的ペアレビュー

さて、同期的ペアレビューの改善点がいくつか見えてきました。

改善点はいずれも同期的に行いすぎていることから来ているようですから、同期的に行いすぎないようにすればよさそうです。しかしペアレビューを行う以上は、「レビュワー同士の能力を補完することで、高速に質のいいレビューを行う」ことを犠牲にはしたくありません。
難しいPRといえど、質問の上がらない簡単な箇所もあります。簡単な箇所については、基本的に非同期レビューとして個々人でレビューを行った方が早いです。

そこで、以下のような半同期的ペアレビューを考えます。

  • ペアレビューなので、時間を揃えて集まってレビューをする
  • PRにチェックポイントを作る
  • チェックポイントに到達するまでは各レビュワーが非同期的にレビューをする
    • 疑問点や指摘点などが出次第必ず発言し、同期的に解決する
  • チェックポイントだけレビュワー全員で同期する
    • チェックポイントに到達した場合は、到達した旨を伝え、全員到達したら次のチェックポイントに向かう

基本的には各人で非同期レビューをすることで、簡単な箇所について高速に精度の高いレビューができます。
しかし何のタイミングも同期しないと、レビュワー間での質問の際に文脈を揃えづらくなってしまいます。チェックポイントを設けることで、チェックポイント間の文脈に閉じた質問をすることができます。ペアレビューで特に行いたい「レビュワー同士の能力を補完する」ことが行えます。
また、チェックポイントを通過した時点で、チェックポイント以前をレビューしきったことを保証することもできます。

基本は非同期でレビューを行う以上、「質問があった場合発言する」ことをより強く取り決めなければなりません。同期的ペアレビューでは、質問箇所に到達したタイミングで質問すればよかったですが、半同期的ペアレビューでは自ら疑問点を解決しにいく必要があります。

チェックポイント

半同期的ペアレビューでは、PRにチェックポイントをいくつか作ります。
具体的には、PRメッセージの各セクションごとにいくつか設定し、コードにもいくつか設定する、といった具合です。
例示したPRの流れに沿うと、以下のようなチェックポイントが設定できます。

  • PRの概要を読み終えるまで
  • PRの動作確認を読み、実行するまで
  • コミットXを読み、レビューコメントを付け切るまで
  • コミットYを読み、レビューコメントを付け切るまで
  • コミットZを読み、レビューコメントを付け切るまで

具体例

Aさん「時間なったのでペアレビューしましょう。今回のPRのチェックポイントは〜〜〜です。」
Bさん「OK」
Aさん「では最初のチェックポイントの『概要を読み終えるまで』をやりましょう」
Bさん「OK」
・・・
Aさん「YYYYYYのような背景があったとのことです、これってどういうことです?」
Bさん「あー、このYYYYYYについては・・・(説明)」
・・・
Aさん「最後にZZをZZZしたとのことですが、これどういう意味です?」
Bさん「私もわかりませんね、考えてみましょうか・・・」
・・・
Aさん「概要まで読み切りました」
Bさん「私も読み切りました。では動作確認に移りましょう」

といった具合に半同期的ペアレビューを進めます。
比べると、「XXXXについての説明は各々理解しているため、時間の短縮ができる」「疑問点や指摘点などが出次第必ず発言する取り決めにより、YYYYYYの疑問点を回収できる」といった点が見受けられます。

こちらもコードを読む際により顕著にメリットが見られると思います。コードの読み方は人それぞれですが、例えば「この関数の使い方が気になった」という質問が挙がったとしましょう。コードを読み方によって「関数」へたどり着くタイミングは違いますが、いずれたどり着くでしょう。この「たどり着くタイミング」をスキップして質問を同期的に解決できます。これが大きな半同期的ペアレビューの性質と言えるでしょう。

まとめ

ペアレビューに起こりがちな同期的ペアレビューの問題を指摘し、改善案として非同期レビューの性質を取り入れた半同期的ペアレビューを説明しました。
使えそうな場面があればぜひ使ってみてください。筆者も他のチームの使用例を知らないので、参考にしてみたいです。

おまけ: 今後の議論

同期しすぎることで起きる問題点は、全部「チェックポイントを用意して非同期で読む」ことで解決できそうな気がします。
「読書会」なんかでも、各人が音読して回し読みするより、チェックポイントだけ同期した方が理解早いかもしれないですね。

株式会社ゆめみ

Discussion