この記事は、KMC Advent Calendar 2022 の10日目の記事です。
また、ten986 Advent Calendar 2022の10日目の記事でもあります。
普段は ten986 Advent Calendar 2022 で個人ブログを開発しながら、そのブログ上にポエムを書く活動をしています(?)
ちなみに体調不良で大遅刻しました。
想定読者
-
既にチーム開発を行なっているが、レビューでのやり取りに課題を感じる人
- メインです
- 特に 品質が重要な チーム開発の場合重要です
- ↑のような人に対して、教える際のチェックリストがほしい人
- 箇条書きにしたので、各項目ごとに意識できると思います
-
チーム開発初心者で、レビュー時のやり取りが分からない人
- 本当はメインターゲットにしたかったんですが、にしては抽象的な内容が多めなので、「こういうことが必要になるんだろうな」くらいの気持ちのがよさそうです
おことわり
個人開発や小規模開発では、必ずしも重要ではないです。
自分の頭にある実装方針が全てである可能性があるためです。
前書き
あなたは企業の製品開発チームのメンバーです。
ここでは日々、実装タスクの洗い出しやその実装、そして Pull Request の作成やそのレビューが行われています。
さて、チーム開発でコードを書いていく上で重要なことは何でしょうか?
チーム開発である以上メンバーで歩み寄りながら開発を進めるべきなのですが、その点で非常に重要になるのが 「実装意図、実装根拠を伝えること」 だと考えています。
実際筆者は、レビュー時のやり取りで 「なぜこの実装にしたか」 と聞くことが多いですが、これは「実装根拠」をすり合わせ、よりよいコードに辿り着くため に行なっています。また、レビューコメントが多くなる場合は、総じて「実装根拠」が伴っていないことが多い と感じており、「実装根拠をコードに乗せ、伝えてくれれば」と思うことがよくあります。
(実装意図が不明瞭である場面は出会っていないと思います。チームのプロセスが順調に動いていることによると思っています)
特に研修段階では、「どのように実装意図、実装根拠を伝えるか」という能力は不足していることが多く、また非常に重要視しているので、特に重点的に教える努力をしています。
そこで、チーム開発を進める上で、なぜ実装意図や根拠を伝えるべきなのか、そしてその伝え方について説明していきます。
チーム開発でどの視点が足りないか? や、どの能力が不足しているか? という気づきになれば幸いです。
この記事での定義
- 実装意図
- どのようなことが実現したいか?
- そのためにはどのようなコードを書く必要があるか?
- 実装根拠
- なぜそのコードが正しく動くのか?
「実装意図や根拠」は伝えるべき
実務でコードを書くうえで、「動くものを作る」こと自体はあまり難しくありません。みんなコードは書けます。
しかし、コードが動くだけではチーム開発では受け入れられません。
なぜならチームで開発する上では、 「どのようなことが実現したいか」 がまずあって、それを実現するためコードがあるためです。コード自体が目的ではないです。
実現したいことさえ伝わっていれば、いくら動かないコードだとしても、レビュワーは修正することができます。レビュワーの脳内でも、「実現したいことから、どのようなコードが書くべきか?」をシミュレーションできるためです。 これが、この記事で言う実装意図です。
そして、コードを書く際には、 「なぜ、このコードで実現したいことが実現できるのか」 が非常に重要になります。
動きそうなコードを書くこと自体は簡単ですが、それが「正しく動くこと」を保証する必要があります。そのため、理由づけをしていきましょう。これが、この記事で言う実装根拠です。
どのようにすれば「実装意図や根拠」が伝えられる?
企業の開発メンバーを想定するため、「動くコード、動きそうなコードが書ける」ことは前提とします。
(この前提が満たされていない場合は、そもそも難しい実装や未知の分野の担当をしていると思うので、実装に入る前にあらかじめ詳しい人がサポートに入るべきです)
実装意図や根拠の伴った「コードを書く」
コードの実装意図や根拠をチームメンバーに伝えるためには、そもそも 実装意図や根拠の伴ったコードを書く 必要があります。
実装意図について
-
実現したいこと が明確である
- 普通、カンバンなどを用いてチケット化されている
- 逆に、チケットは実現したいことが明確であるべき
- (この記事の前提条件である)
-
実装範囲 が明確である
- これも、普通チケットで範囲が定められている
- (明確でない場合、複数回実装されたり、実装漏れが起きたりする)
- これらの実現したいことが、コード上のどこで実装されているか? が分かる
- これらはチームの方針に寄るところが多く、「どのように書くか」「どこまで具体的に書くか」はチームで合意が取れているとよい
実装根拠について
-
「上手く動く理由」が明確に説明できる
- 理由づけがなければ、それは 「なぜか動くコード」 でしかなくなる
- レビュワー視点ではこの「理由づけ」を試みるので、 「なぜか動くコード」に対しては理由づけが効かず多くのコメントが付く
- 理由づけがなければ、それは 「なぜか動くコード」 でしかなくなる
-
言語やフレームワークの知識 を用いて説明できる
- 「この記述だとこういう挙動をするから・・・」 など
- 知識に基づいて、「別の実装方法はなかったか?」が検討余地
- あまり知られていない知識(自分の知らない知識)は、信頼できる情報源 を用いる
- 言語やフレームワークについて詳しくない場合は、調べていく
- これについては 「検索力」 は必要になる
- 調べれられない or 面倒であれば、他のメンバーに聞いてもよい
- 開発においては、既存実装を参照する 場合も多い
- この場合、 既存実装の実装意図 を必ず考えること
- 実務のコードには基本的に実現したいものが背景に存在し、結果であるコードのみを見ても信用できない場合もある
- 逆に実装意図が分かれば、ガンガン再利用して効率化してよい。コピペ上等
- ドメイン知識についての情報源は、開発体制による
-
情報源は、可能であれば共有する
- 自明な知識は共有しなくてもよい場合があるが、慣れなければ共有する方向でよい
- 言語やフレームワークについて詳しくない場合は、調べていく
-
設計方針 が適切である
- 上手く動くにしても、実装によって今後の実装に影響が出ることもある
- コードに触れていたり、知見を収集していたり、製品の朽ちる様子を見たりする必要がある気がする
- すぐ得られる知識というより、経験は必要
-
上手く動くことを検証する
- 動作確認をする
- テストコード実装
実装意図や根拠を「伝える」
さて、コードに実装意図を乗せることができれば、 実装意図を伝える ことができるようになります。
- 大前提として、正直に伝えること
- 「自分が知らないこと、分からないこと」を隠したい気持ちを捨てて、自分の知ってる情報を正確に伝えることを意識する
- 「分からない」と言えば、その知識は教えてくれる
- レビュワーは怒りたいわけではなく、対話をしたいので
-
正確に伝えること
- 「正確に文章で伝える方法」に自信がない場合は、 テクニカルライティング について調べるとよい
- すでに良記事が多く存在していると思う
- 「正確に文章で伝える方法」に自信がない場合は、 テクニカルライティング について調べるとよい
-
実装時に考えたことを伝える
- 「このような背景があった」
- 「このような対策をするとよい結果が得られた」
- 「逆に、これはダメだった」
- 「結果、このような実装になった」
- これらは実装した本人なら分かるが、他の人には非自明な情報 である
- レビュワー視点としてもエスパーすることは不可能ではないこともあるが、実装した本人が伝えるのに比べて非常にコストが高い
- コードやPRのメッセージを見れば、実装意図や根拠が伝わる状態にする
-
適切なコメント、命名、ファイル整理 などにより、実装意図は伝えられることが多い
- そのため、あえてメッセージで明記しなくても伝わる
- (伝わってしまうが、その影響でメッセージを書かなくていいと勘違いしてはいけない)
- この辺りは記事も多く、命名だけで記事になったりする
- そのため、あえてメッセージで明記しなくても伝わる
-
対応したチケット を書く
- チケットに書かれていることからズレた対応範囲があれば、明記する
-
上手く動くことの検証方法 を書く
- 動作確認方法
- 自分が検証した時は自明でも、他人が知らない情報は結構ある
- 伝わらなかった場合には、「コメント」がつく
-
適切なコメント、命名、ファイル整理 などにより、実装意図は伝えられることが多い
実装意図や根拠で「話し合う」
ここまでができれば、「実装意図の伝わる Pull Request」が出せるでしょう。 そうすれば 「実装意図を元にしたレビュー」 ができるようになります。 これも少しコツがいると思うので、まとめていきます。
レビューする側
-
「実装意図」を汲み取る
- 「実現したいこと」があってのコードなので、それを必ず理解する必要がある
- レビュワーは実装意図を理解する必要があるものの、実装意図に対してレビューすることはあまり多くないはず
- レビューとは別のプロセス(チームの会議や、PR以前のチャットなど)で方針を定めておくべきなので
- 正しく動かなかった! ということはあるが、それは「正しい挙動 ≒ 実現したいこと」が存在するから
-
「実装根拠」を理解する
- 基本的にレビュワーの仕事はここであってほしい
-
設計方針 について考える
- 「実装根拠」に挙げた一番難しいポイントなので
-
レビュワー視点による「実装意図」「実装根拠」を考えた上で、レビューする
- コードが正しく動くだけでは不十分
レビューを受けて
-
「この部分を直してください!」 とコメントをされた場合
- レビュワー視点での「実装意図」「実装根拠」の方が上回っているので、普通はその通りに直せばよい
- 「修正しました!」程度のコメント返しでよい
-
「このような実装の方がよいと思います」 とコメントされた場合
- レビュイー、レビュワーのどちらが良いか不明 だが、「実装根拠」はレビュワーから提示されている
- 明らかにレビュワーの根拠が強い場合
- 「自分はこのような根拠で書きましたが、そちらのがよいと思うので修正しました!」のようなコメント返しになる
- 明らかに自分の実装根拠の方が強い場合(少しレア)
- 「自分はこのような根拠で書いたので、修正していません」のようなコメント返しになる
- 実装根拠となるソースを提示すると、伝わりやすい
- 重要なのは、コメントされても修正が必ずしも必要ではないということ
- どちらの主張も通る場合
- 明らかにレビュワーの根拠が強い場合以外は、大体こうなる
- そして、やりとりが多くなる
- 往復が少なそうならPR上でやりとりしてもよいし、面倒なら同期的ミーティングをしてもよい
-
「なぜこのような実装になっているのですか?」 とコメントされた場合
-
質問 であるので、基本は 「実装意図」「実装根拠」 について自分の意見を返せばよい
- 例外を除き、特にコードの修正は必要ではないことが多い
-
「実装意図」「実装根拠」 が不明瞭の場合が多い
- PRのメッセージに追記することで、伝える
- (例外)コード上で、コメントや命名などを変えることで、不明瞭さがなくなることもある
-
質問 であるので、基本は 「実装意図」「実装根拠」 について自分の意見を返せばよい
逆に、「実装意図や根拠」を伝えてもらう側として必要なこと
長々と「伝える側」について書きましたが、伝えてもらうためには 環境 も重要です。
-
分からないものは分からないと言える環境
- 心理的安全性 は大事
- 「分からない」と言ったら評価が落ちるかも・・・と思わせてはいけない
-
ドメイン知識についての情報源
- 実装根拠のところで書いたが、アクセスしやすいドキュメント体系が必要
-
時間
- 時間が限られている場合、品質どころではない