はじめに
コードレビューは、バグの早期発見やチームの知識共有など、多くのメリットをもたらす開発プロセスだ。
しかし、レビュアーに「このPR、何から見ればいいんだ...」と思わせてしまうPRを出し続けていないだろうか。
レビュアーが消耗する原因の多くは、レビュイー側の「思考の習慣」にある。
コードの書き方の問題ではなく、実装に取り掛かる前から、PRを提出するまでのプロセス全体に問題が潜んでいることが多い。
この記事では、駆け出しエンジニアに向けて、陥りがちなパターンを整理しつつ、現場やツールを問わず普遍的に役立つ思考の習慣をまとめた。
よくある失敗パターン
まず、駆け出しエンジニアがやりがちな問題を把握しておこう。
- 大きすぎるPR:設計から実装まで1週間分をまとめて提出してしまう
-
意図が伝わらない説明:タイトルが
fix bugだけ、本文が空 - 汚い差分:改行やフォーマット修正が本質的な変更に混入している
- 粗いコミット:動作確認できない単位でコミットが積まれている
- 設計の認識合わせなし:方針を確認せず実装を始めてしまう
- 自己レビューなし:自分のdiffを一度も読まずに提出している
これらはすべて「実装の問題」ではなく「プロセスの問題」だ。
順を追って解説していく。
1. 実装前:まず「考える」
最も重要なのが、実装に入る前の思考プロセスだ。
依頼を受けたら即コードを書き始めるのではなく、以下の順序で考える習慣を持つべきだ。
機能追加依頼
↓
① そもそもシステムに落とし込むべきか?
↓(必要と判断)
② 既存機能で代用できないか?
↓(できない)
③ 既存機能の拡張で対応できないか?
↓(できない)
④ 新規機能として構築する
↓
⑤ 詳細設計を行う
↓
⑥ リファクタを先に行い、土台を整える
↓
⑦ 実装
このフローは実は、ソフトウェア開発の世界で広く知られている原則と対応している。
| ステップ | 背景にある概念 |
|---|---|
| そもそも必要か | 要件定義・フィジビリティスタディ |
| 既存機能で代用 | YAGNI(You Aren't Gonna Need It) |
| 既存機能の拡張 | 開放閉鎖原則(OCP) |
| 詳細設計してから実装 | 設計ファースト |
| 先にリファクタ | Fowler「機能追加前に土台を整える」 |
このステップを飛ばして実装を始めると、「方向性が根本的に違った」という設計レベルの手戻りが発生しやすくなる。それがそのままPRに現れ、レビュアーを困らせる原因になる。
設計段階でレビュアーと認識を合わせる
大きな改修の場合は、実装に入る前に設計段階でレビュアーへ相談することを推奨する。
この一手間が、実装後の大規模な手戻りを防ぐ最も効果的な方法だ。
2. 実装中:コミットを「動く単位」で積む
実装中に意識すべきことは2つだ。
コミット粒度を小さくする
コミットは「動作する最小単位」で積む習慣を持つべきだ。
1コミットに複数の変更を詰め込むと、後からどこで何が変わったかを追えなくなる。
悪い例
feat: ユーザー登録機能を追加、バリデーション修正、不要なファイル削除
良い例
refactor: ユーザーモデルの不要なフィールドを削除
feat: ユーザー登録APIのエンドポイントを追加
feat: ユーザー登録のバリデーションを実装
「正常に動く範囲でコミットする」という原則を守るだけで、レビュアーが変更の意図を追いやすくなる。
不要な差分を混入させない
本質的な変更と関係のない差分(インデントの統一・改行の追加・コメントアウトのみの変更など)は、レビュアーの集中力を奪う。
実装前に対象ファイルを整理する際は、リファクタ用のコミットと機能追加のコミットを必ず分ける。
同じコミットに混ぜてしまうと、「この変更は意図的なものか、ミスか」の判断をレビュアーに強いることになる。
3. PR作成前:自分でdiffを読む
PRを出す前に、必ず自分でdiffを一読すること。
これは最も簡単かつ効果的なセルフレビューだ。
確認すべき観点は以下の通りだ。
- デバッグ用の
console.logやコメントアウトが残っていないか - 意図しないファイルが変更に含まれていないか
- コミットメッセージが変更内容を正確に表しているか
- PRのサイズが適切か
PRサイズの目安
| 規模 | 変更行数 | レビュアーの体感 |
|---|---|---|
| 小 | ~200行 | サクッとレビューできる |
| 中 | 200〜400行 | 集中すれば1回で見られる |
| 大 | 400〜800行 | 複数回に分けて見る必要がある |
| 巨大 | 800行〜 | レビュアーの集中力が限界を超える |
ただし、行数だけが基準ではない。
テストコードや自動生成コードが大半を占める場合は800行でも問題ないこともある。
一方で、ロジックが密集した200行は非常にレビューコストが高い。
「レビュアーが1〜2時間で理解しきれるか」 を基準として考えるのが実用的だ。
PRが大きくなってしまう場合の分割方法
やむを得ずPRが大きくなる場合は、以下のアプローチで分割できないか検討する。
- レイヤーで切る:DB変更 → ロジック → UI の順に別PRにする
- 段階で切る:最小動作するところまでを先にPRにし、残りを後続にする
- 準備PRを先に出す:リファクタや型定義だけを先行PRにして、本体を見やすくする
- フィーチャーフラグで隠す:フラグで機能を隠した状態でマージし、PRを小さく保つ
どうしても分割できない場合は、以下の対処をとる。
- レビュアーに「このファイルから見てほしい」と読む順序を伝える
- PR説明にアーキテクチャ図を添付する
- PR上に自分でコメントを先に入れておく(「ここは意図的にこうしています」)
4. PR作成時:改修意図を言語化する
PRの説明文は「レビュアーへの手紙」だ。コードだけ投げて「あとはよろしく」では、レビュアーがコードを読む前に多くの時間を「解読」に費やすことになる。
最低限書くべき内容
① 背景・課題 なぜこの改修が必要なのかを書く。
## 背景
ユーザー登録時にメールアドレスの重複チェックが行われておらず、
同一メールアドレスで複数アカウントが作成できてしまう問題があった。
② 対応内容 何をどう変えたかを書く。
## 対応内容
- ユーザー登録APIにメールアドレスの重複チェックを追加
- 重複時は400エラーを返すように変更
③ 技術的な選択の理由(必要に応じて) 「なぜこのアプローチを選んだか」を書く。レビュアーが「なぜ?」と感じそうな箇所は、先に説明しておく。
## 補足
既存の`UserValidator`クラスを拡張する方法も検討したが、
バリデーションロジックとビジネスロジックの分離を優先し、
サービス層に実装することにした。
タイトルの書き方
タイトルだけでPRの目的が伝わるように書く。
| 悪い例 | 良い例 |
|---|---|
fix bug |
fix: ユーザー登録時のメールアドレス重複チェックを追加 |
update |
feat: 商品検索に価格フィルターを追加 |
修正 |
refactor: ユーザーモデルの不要なフィールドを削除 |
5. レビュー中:指摘を「自分の成長」として受け取る
レビューで指摘を受けたとき、どう向き合うかもレビュイーの重要なスキルだ。
返答するときの原則
- 対応方針を明示する:「修正します」だけでなく「〇〇の方法で修正します」と書く
- 理解できない指摘は質問する:黙って修正するのではなく、意図を確認する
- 議論が長引いたら場を変える:コメント上での議論が3往復を超えたら、口頭やチャットで解決する
指摘されたことを次に活かす
指摘内容はメモしておき、次のPRに反映する習慣を持つ。
同じ指摘を繰り返されることは、レビュアーにとって最もコストが高い。
まとめ:PR提出前チェックリスト
【実装前】
□ 既存機能で代用・拡張できないか検討したか
□ 大きな改修の場合、設計段階でレビュアーと認識を合わせたか
【実装中】
□ コミットは「動く単位」で積んでいるか
□ リファクタと機能追加のコミットを分けているか
□ 不要な差分(改行・フォーマット修正など)が混入していないか
【PR作成前】
□ 自分でdiffを読んだか
□ デバッグコード・コメントアウトが残っていないか
□ PRのサイズは適切か(目安:400行以内)
□ 大きい場合、分割できないか検討したか
【PR作成時】
□ タイトルだけでPRの目的が伝わるか
□ 背景・対応内容を説明文に書いたか
□ 技術的な選択の理由を書いたか(必要に応じて)
□ レビュアーが迷いそうな箇所にコメントを入れたか
【レビュー中】
□ 指摘への対応方針を明示しているか
□ 理解できない指摘は質問しているか
おわりに
「相手が読みやすいPRを出せる」ということは、「自分の思考が整理できている」ということでもある。
レビュアーのためにやることが、そのまま自分の設計力・実装力・コミュニケーション力の成長につながる。現場やツールが変わっても、ここで紹介した思考の習慣は普遍的に役立つはずだ。
最初はチェックリストを見ながら機械的にやるだけでいい。
続けるうちに、確認しなくても自然とできるようになる。