Code Reviewのレビュアーへの考慮

2022-07-04 Mon 00:00

コードクオリティーを測る唯一の指標はコードレビュー時に「なんだこれ?」とつぶやく回数
—Redditの人

Redditの人が言うようにコードレビューをするときに理解に苦しむときありますよね。この問題に対して考えたものを書きます。

コードレビューが難しい理由は何?

この回答を出すために、僕はまず自分が他の人のプルリクのコードレビューをしたときの思い出をまとめてみました。

2022-07-04_18-44-16_screenshot.png

レビューを諦めたときと、しんどかったときの内容をカテゴライズしてみました。

2022-07-04_18-44-46_screenshot.png

その結果問題は以下の三点になりました。

  • プルリクの説明がわかりにくい
  • コードがわかりにくい
  • コミュニケーションとってくれない

それぞれの問題を解決していきます。

※ 情報あつめの時間を省いているため、自分の思い出たちのみの情報で問題定義と解決策の提示をしています。抜け漏れはおそらくあります。ご容赦ください

プルリクの説明がわかりにくい問題の解決策

諦めた思い出と、しんどかった思い出に対して解決策を軽く出して見ました。

2022-07-04_18-53-14_screenshot.png

大体は「正確な説明を書くのをサボらない」を実施したら解決できそうです。
「仕様がわからなかった」に対しては理解した思い出である「仕様のフローチャートがあった」ときを参考に仕様のフローチャートを作ることを解決策にしました。

たまたま僕はPlantUML Gladiatorなので仕様を書くツールを紹介します。

PlantUMLの紹介

フローチャートを書くツールはたくさんありますが、たいていGUIでマウスを使って箱や矢印を作ります。ですがTyping Emperorの僕にはマウスを使った繊細な作業が効率よくできませんでした。
そこでテキストでUMLの図を作成できるツールのPlantUMLです。テキストをタイプできればいいのでVimでもEmacsでもIntelliJでもできます。

2022-07-04_18-54-26_screenshot.png

PlantUMLで作成できる図はUML以外にもありますが、主にUML を書くのでUMLの紹介もしておきます。

UMLの紹介

UML(Unified Modeling Language)はシステムのデザインを表現できる図です。大きく分けて振る舞いを表す図と構造を表す図の2種類に分類されます。使い所がそれぞれ違い、用途にあった使い方をすればプログラマーの作業の大半に役立つPowerful Weaponになります。

ビジネスサイドに人とのやり取りにはシステムの振る舞いを表す図が役立ちます

  • Use Case Diagram: システムの機能とシステムを使う人の関係
  • State Machine Diagram: 状態がどう変化するのか
  • Activity Diagram: システムのフロー

プログラマーとのやり取りには上記の図とともに、構造を表す図も役立ちます

  • Deployment Diagram: アプリケーションの構成
  • Sequence Diagram: 処理の順序と処理を行うオブジェクト(これは振る舞い)
  • Class Diagram: オブジェクトの詳細と関係性

色々なUMLがあるのですべては紹介しないですが、個人的に一番役に立っているActivity Diagramの特徴を紹介します。

2022-07-04_18-56-01_screenshot.png

メリット

  • ビジネスサイドの人も理解できるため、仕様確認の際に活躍する
  • プログラマーにもざっくりどういう実装なのかがわかるためレビューしやすい

デメリット

  • ループも書けますが、図が難しくなって逆に読みたく無くなる可能性があるため使うときは要注意
  • 特別な表記は事前共有が必要かも

UMLの紹介は以上です。

PlantUMLを使う上でのメリット・デメリット

先ほどちょっとPlantUMLのいいところを紹介しましたが、デメリットとともにリストアップします

メリット

  • タイプするだけでいいし、レイアウトも気にしないでいいためUML作成が早い
    • 個人的にはこれが一番のメリットです。素早く図がかけるとストレスなくたくさん作ることができます。
  • テキストのため、 Version Controlできる
    • Source Control配下におき、仕様がコードと同じところにあると簡単に確認ができ、図の更新もしやすいです。
  • 色々なIntegrationがある(GitLab, Markdown, IntelliJ, VSCode)
    • GitLabで PlantUMLを使えるためビジネスサイドとの確認やプルリクの説明に役立ちます。

デメリット

  • 学習コスト
    • 言語なのでSyntaxを習う必要があります。
  • レイアウトの修正は難しい、または不可能
    • AWSのネットワーク図、複雑なApplication Architectureの図、などはPlantUMLに適してないです。

これでPlantUML説明は終わりです。機会があればぜひ使ってみてください。

コードがわかりにくい問題の解決策 

しんどかった思い出に対して解決策を出しました。

2022-07-04_18-57-52_screenshot.png

今回の解決策は「変更が多すぎたら別プルリクにする」と「Docを書く」と「コミットごとにレビューできるようにする」にしました。本来なら「コミットごとにレビューできるようにする」ではなく「一つのプルリクに対して1つのことしかやらない」で解決になりますが、依存関係を持った複数のブランチを管理する大変さを知っている僕はそれを解決策にしませんでした。
「変更が多すぎたら別プルリクにする」と「Docを書く」は簡単に実現できそうですが、「コミットごとにレビューできるようにする」はいつもどおりのコミットではできません。

偶然にも僕はGod Level Git Fighterなのでコミットごとにレビューできるようにする方法を紹介します。

コミットごとにレビューできるようにしたらどうなるのか?

でもやっぱり「コミットごとにレビューできるようにする」を実施したらどのくらいコードがわかりやすくなるか気になりますよね。

まずコードがわかりにくい方を見てみます。

2022-07-04_18-58-33_screenshot.png

やりたいことが3つあり、その実装が色々なコミットにばらまかれてます。これがわかりにくい理由は

  • コミットごとに見ても分かりづらい
    • コミットを見て「やりたいこと」の実装方法を理解しても次のコミットでまた変更があると何が最終形態なのかわからない
    • 一つのコミットに結局2つの「やりたいこと」を実装しているためどの修正がどのやりたいことなのかをマッピングする必要ある
  • 変更ファイルすべて一気に見ても分かりづらい
    • すべての修正からやりたいことが3つにマッピングする必要がある

今度はわかりやすい方を見てみます。

2022-07-04_18-59-23_screenshot.png

やりたことが3つあり、その実装がコミットごとに別れています。これは一つのコミットにやりたいことが集約されているため、コミットごとにレビューをすればわかりやすい。Conventional Commitというコミット方法を使えば自然とわかりやすいコミットになります。

Conventional Commitってなに?

コミットの単位を目的ごとに切り分けるコミット方法です。

大体下記のような目的を使います。

  • feat: 機能開発
  • refactor: リファクタリング
  • test: テストの追加、変更
  • doc: ドキュメントの追加、変更

でもConventional Commitに則ってコミットしていっても問題に突き当たります。
一発でちゃんと目的ごとに切り分けたコミットにするのはめちゃ難しいです。

例:
Conventional Commitでできるはずのコミットログ

refactor: 変数名変更
feat: 記事検索機能の実装
test: 単体テストの追加

実際にできたコミットログ

1. feat: 会員登録機能の実装(リファクタリングも混ざってる)
2. fix: 新規機能のバグ(1のバグ発見)
3. fix: まだバグってた(1のバグ発見)
4. test: tんタイテスタのついk(Typo)
5. feat: 文言修正(1の文言間違えの修正)

これを解決するためには git rebase を習得したら解決できます。

Git rebaseってなに?

ブランチを派生場所を変更する git command です。以前のコミットをすべて削除され、新しくコミットが別の場所に追加されます。

Atlassianの説明がわかりやすいので見てみてください。

このコマンドを使うことにより以下のことが可能になります。

  • コミットメッセージの変更
  • 複数のコミットを一つにまとめる
  • 一つのコミットを複数に分ける

これでコミットを間違えても修正が可能となり、ちゃんとしたConventional Commitになります。

2022-07-04_19-08-44_screenshot.png

ですがこのコマンドには危険が伴います。複数人で編集しているリモートブランチに対して git rebase をしたら 他の人の修正が消える可能性 があります。注意して使ってください。
git rebase のやり方は説明が難しく、やってみないと習得できないのでここでは説明しません。直接僕に聞いてくれたら喜んで教えます。

以上でコミットごとにレビューできるようにする方法の説明は終わりです。これやるととんでもなくコミットきれいになり、レビュアーが踊りだすのでやってみてください。

コミュニケーションとってくれない問題の解決策

思い出に対して解決策をまた出しました。

2022-07-04_19-09-40_screenshot.png

シンプルでいい解決策ですね。

終わりに

レビュー依頼を出す前に下記ができており、レビュアーのコメントに返事をすることでレビュアーが諦めることやしんどくなることがなくなるはずです。

正確な説明を書く
仕様のフローチャート作成
変更ファイル数は20以下
Docを書く
コミットごとにレビューできるようにする
コメントに返事する(これはレビューに出したあと)

ここで一句