👨‍👩‍👧‍👦

個の最大化とチームの最大化を目指すために考えるべきこと

2021/07/04に公開

こんにちは、クレスウェアの奥野賢太郎です。今回は私の職業でもあるSaaS開発者という視点から、コードレビューに対する日頃の考えをまとめます。技術系の内容はQiitaに書くことが多いですが、今回はどちらかというと思想・哲学や日々の振る舞いに近いテーマとなるので、非技術系の方にも広く読んでいただきたく、noteでの掲載としました。

この記事でお伝えしたいこと

・コードレビューの本質はコードのレビューではない
・チームの健康維持を目的に個のパフォーマンス、チームのパフォーマンス両方の最大化を目指す
・理想と現実を見つめるフェーズは異なる、2つの視座を持つ

SaaSとは

このnoteのフォロワーには技術系だけでない方もおられるので、簡単にSaaSについて説明します。

SaaS(サース)はSoftware as a Serviceの略で、ざっくりと表現するならばブラウザ上で動作するアプリのことと思ってもらってよいです。たとえばGMailやOffice365、Slackといったもの。最近は会計や人事の領域でもこうしたSaaSが増えており、家電屋でアプリケーションの箱を買って、パソコンにインストールするといったことが無くなりました。

私はこうしたSaaS(以下、アプリ)の設計や開発を日々の業務としています。アプリは、プログラミング言語を用いて書かれたコードの膨大な蓄積によって成り立っています。そして、アプリ内の機能が増えれば増えるほどコードの量も増え、一人での開発が困難となり、複数人のチームでの開発体制を取るようになります。

チームを結成すると、そこに小さな社会が形成されます。チームで開発を進めると、そのチームメンバーの知識の差、スキルの差、好み、性格が反映され始めます。我々はロボットの集団ではないので、完全に均質な開発など不可能です。好みを押し殺し性格を無にしろという職場では、働きたくありませんから。

コードレビューとは

コードレビューとはなにか、そしてなぜ必要か。例えば、3つの画面を持つ1つのアプリを作るとき、3人1組のチームで、1人が1画面分の開発を担当したとしましょう。みんな思い思いの実装(プログラムを書くこと)を進めてしまうと、こっちの画面とあっちの画面で使い勝手がバラバラになる恐れがあります。同じ機能にも関わらず、片方の画面でのみバグが起こるかもしれません。

この問題を防ぐために多くの場合、仕様書というテキストが用意されます。そして、その仕様書を基にプログラミングしていく際に齟齬なく実装ができているのか、誤解が生まれていたりバグが混入していないか、チームのお互いがコードを読んで確認する作業をします。これをコードレビューといいます。執筆における校正に近いと思ってもらってよいです。

何をレビューすればよいか

さて、ここから私は技術系の読者、技術系ではない読者の両方に宛てた記事として提供します。というのも、コードレビューというのは一見「プログラミングされたコードを読んで、そのプログラムの誤りを指摘する行為」に見えますが、実はとても社会的な行為であり、日々のあらゆる考え方に応用が可能であるため、その一端を広く知っていただきたいからです。

コードレビューで何をするか、それはもちろんコードのレビューです。なのですが、ただコードを漫然と眺めて感想文を書いただけでは生産的ではありません。レビュー対象のコードから何を読み解き、レビュアーはレビュイー(実装者)に対して何を伝える必要があるのか、そこから考える必要があります。

私はこのキャリアに就いて6年目ですが、幸い1年目からコードレビューをする立場、される立場の両方を経験することができました。そしてこれまでのキャリアの中で、どの組織でも数人から10人足らずほどのチームに所属しています。それらで学んだことを積み重ねた最新の見解として、コードレビューは案外コードを読むだけではないことに気付きました。

コードレビューでは、チームの健康をレビューします。

健全なアプリは健康なチームから

開発の現場であってもなくても、精神・身体ともに不健康な職場で働くのはつらいものです。常に健康でありたいです。

例えば、バグが多いアプリを生み出してしまったとして、その無数のバグの解消が困難で連日徹夜をしてしまったとしたら…不健康ですね。そのため、バグの原因となりそうなものは、バグとして発現する前にコードレビューで指摘し除去します。これでバグ取りのために徹夜をすることが減り、健康。

…という観点の健康も合ってはいるのですが、それだけではありません。実は、日々の些細な疑問の蓄積によるストレス、口には出さないけど抱いている不満、手間が多い作業を繰り返す憂鬱、といった「何気ない日常での蓄積による阻害」が健康に対して与える影響は大きく、その対策がとても肝要となるのです。

コードレビューでは、これらに対して目を向ける必要があります。

個の特性に目を向ける

先に述べたように、チームで開発を進めていくとそこに社会が生まれます。複数の人間が関与している以上、全員があらゆる事象に対して常に同じ見解を持つはずがありません。

これは健康を害する尺度についても同様です。神経質な人、大雑把な人、色々います。日常の小さな問題に気にならない人もいれば、とても気にしてしまう人もいる。私は、性格はとくにプログラミングに影響を与えると思っています。

多くの開発者のコードをレビューしてきた結果、新しいチームでも何度かレビューを重ねれば、コードを読むだけで誰が書いたものなのか、担当者を見ることなくおおよそ当てることができます。

「Aさんらしいコードだな」「この内容はBさんらしいな」「おっと、この機能の担当者はCさんなのに、らしくないコードだな?」といった具合です。らしくないコードの場合、当人が実装時に疲れていて判断力が鈍っていたり、他の開発者のコードをコピペしていたり、といったことが実際あります。

コードレビューの対象となるコードは、日々の差分(コードの追加部分、変更部分)という断片であることが多いですが、その断片からチームの各担当者のコンディションを見極めるのです。例えば、今日は調子がよさそうだとか、今日は悩みが多そうだ、といった具合です。

理想の追求と現実の追求

チームメンバーによってコードの癖が透ける事実があるほど、個というのはチームに対して意外と影響を与えています。そのため、各個人が全員横暴な振る舞いをしてしまうと、チームの健康は損なわれ始め、途端にアプリ全体の品質維持は困難となります。

アプリはどういう品質であってほしいか、これを決めるのは、多くの場合その組織の経営者やプロダクト・オーナーといった立場の人間です。そしてその品質に対する期待を維持し続けるため、我々開発者は何を指針に開発していけばよいのか。それを定める行為が「設計」です。アプリ開発における設計は、品質を定めることではなく、定められた品質に近づけて維持していくためにはどうすればよいか、考えることです。

ある意味、設計は理想です。そもそも、多くのプロダクトの目指す品質が理想論であることが多いため、そこに近づく手段を模索することも同時に理想論になりがちです。ただ、ここで述べている設計とは、もちろんひとつの側面に過ぎないことをご了承ください。

設計が全体的な理想の追求だとすると、コードレビューは、理想に対する日々の距離を確認する行為となります。そこで日々理想を追求するのは、もちろん品質を高める上で必要ですが、負の側面を持ち合わせています。それは、注意しないと個への理想の押し付けになってしまうという懸念です。

大半のケースでは、そのチームメンバーはその組織に賛同して所属しているため、全体認識として高い品質を維持したいという思いは共通のはずです。気をつけるべきなのは、品質の理想をレビュアーの理想に再解釈した上で、そのレビュアーの理想が押し付けられてしまう場面です。これは一見、全体の共通のゴールを目指しているように見えますが、ただのエゴに成り下がってしまいます。

私は、コードレビューをする上での尺度として、全体のゴールはどこか、今どうあるべきかを常に見極めながら考えます。一律で理想を振りかざすのではなく、理想に近づくために今どこまで進むか、あるいはあえて理想から遠のく判断を下すか、といった選択をします。これは現実の追求といいます。

個の最大化

スキル、性格は毎日頻繁に変わるものではありませんが、体調、頭の回転といった身体的な変数は日々変わります。得意分野で波に乗っている開発者と、不得意な分野を任され疲弊している開発者に等しく理想を展開することは、チームの健康を維持する上で避けなければなりません。

コードレビューによって、疲弊した開発者へはガイドを提示し、波に乗っている開発者に対してはその波を阻害せず長続きするようにする。各個人のパフォーマンスの維持を優先して考える、これを個の最大化とします。

私は理想の観点からのコードレビューをせずに、現実が理想からどこまで遠のこうとしているかでコードレビューをします。つまり、理想から大幅に遠のいてしまうようであれば、現状維持をするためにどうすればよいかで意見します。大幅に遠のいてしまうことは避けつつも、欲張らない理想の追求…つまりは現実の追求です。

これは前半に述べた健康なチームの維持のために大切です。ゴールから離れず、かつ快適に開発に従事してもらう環境を提供することがレビュアーの務めです。コードレビューが理想の追求ではなく、チームの健康をレビューすることであると述べたのは、このためです。

具体的にいうと、リファクタリング(コードの改善)が可能な状況であれば、現状のコードが最善ではなかったとしても、それを許容します。逆に、リファクタリング不可能なコードについて、それは品質の理想から離れ続ける方向であるため、指摘するようにします。

チームの最大化

個人のパフォーマンスを最大にしつつも、その最大化されたものがあらゆる方向を向いていてしまっては、ひとつのゴールに向かえません。チームとして共通のゴール、つまり理想の品質に到達すべく、どうするのがよいか。チームの最大化もあわせて考える必要があります。

チームは社会であり、これは民主主義です。レビュアーがたとえチームに1人だったとしても、この者は独裁者ではないのです。チーム全体を最大化するための施策は、チームの合意によって導入せねばなりません。

個の最大化をしつつ、全体を束ねるための施策を導入する…、たとえばフレームワークの採用であったり、コードフォーマッタ、Lintルールの採用といった技術の活用によるルールの導入です。

これを私はよく交通法規に例えます。プロのレーサーであっても、一般道を300km/hで走ったりはしません。これは社会の安全を優先し設けられた法律です。

ルールは理由を持って定められます。チームの場合、チームの健康維持、チームの方向性の認識とパフォーマンスの最大化のために、そのルールが必要かどうかで判断します。特に、重ねて述べているように、チームが健康でいられるかどうかの観点が重要です。神経質な人が多かったり、大雑把な人が多かったりと、チームを構成するメンバーの性格によって、このルールは日々見直す必要があります。

これらはチームで民主的に決まるのがよいですが、多くのチームではなかなか言い出されないまま、健康を密やかに損ない続けている例が多いです。そのためコードレビュアーに限ったことではないですが、何らかのオピニオンリーダーが求められます。私は結果的に、設計者やコードレビュアーとオピニオンリーダーを兼任しています。

コードレビューでは、なるべく個人の意見を出さないように注意します。もちろん自分の経験上「こっちの方がいいかもしれない」という内容を述べる状況は存在します。そういった際は、自分の経験と自分の考えであること、自分の経験上そうしなかった場合に何が起きたかを明記するようにします。親しい間柄の仲間であれば、そこを省略することもありえますが、原則的に根拠や出典を添えるよう心がけています。

根拠や出典たりえるものとしては、世界で広く認められた名著や、名エンジニアの格言、世界中の開発の現場で問題とされてきたものをパターンとしてまとめた資料、といったものを扱います。

複数の業種が交わる場でのレビュー

現在私は、株式会社トレタに社外アーキテクトとして参画しています。ここでは開発が進むチームの日々のコードレビューだけでなく、多くの仕様書、画面デザイン定義書、サーバーの定義書と触れる機会が多く、それらのレビューもします。

サーバーアプリケーションの開発は、開発者として同職種ではありますが、仕様書の作成やデザインの作成は、異なる職種の方々となります。そういった方々に対するレビューについても、これまでと同様の尺度を持って臨みます。

つまり、ここまでコードレビューとは呼んでいますが、それは、組織がなにかを世に出すまでの社会形成を円滑にするためのコミュニケーション手法と、それを達成するための頭脳労働と言い換えることもできます。具体的なコードレビューは全体のコミュニケーション手法の一種に過ぎず、相手が誰であっても、どの職種であっても、目指すところと現実との距離について認識し、客観的に方向性を述べていくことが必要なことに、変わりありません。

プロジェクトマネージャーやディレクターとの職種の違いですが、それらのポジションが人事、工数、お金を管理することだとしたら、私のポジションは、提示された理想に対する技術的な距離を測り、その日採るべき行動に導くという、より具体的な一手を考えるポジションといえます。

コードレビューの2つの視座

最後に、私のコードレビューには2つの視座があることを紹介します。

ひとつはこれまで述べたように、チームの健康を最優先にしたコードレビュー。もうひとつが、徹底的なまでの品質の理想に対する、現状把握を目的としたコードレビューです。

理想より現実…、というのは日々の業務を健康に進めるために重要であるのですが、一方で妥協の蓄積が発生してしまう問題も含みます。理想から遠のくことをよしとする判断も、蓄積してしまうと品質から遠のきすぎてしまうのです。

そこであえて、私は現状のコードすべてに対して徹底的にコードレビューをし直します。ここで気をつけるべきなのが「そのコードは誰が書いたか」を一切気にしないことです。それは、その人の悪い癖を見つける場ではなく、客観的に今アプリが品質に対してどの位置にいるかだけに注意を向けるためだからです。そして、そこで挙げた懸念点や改善点について、誰のせいにするでもなく、ひたすらチームの課題として列挙していきます。

これは年に数回という頻度でよいと思っていますが、全くやらない状況より、得られるものがとても多く、やったほうがよいです。日々のコードレビューとは視座が違うため、気付く点がとても多いのです。

そしてこういった機会に挙がる問題点は、実はチームの何人かが、言わずとも日々気にしていた問題だったりします。そのためこういった機会での解消もまた、チームの健康維持に寄与します。また、その組織が目指すビジネスにおける長期的な懸念を発見する機会でもあります。

コードレビューは快適に業務を進めるための知恵

チームでの開発を進める開発者の多くは、コードレビュアー、あるいはレビュイーを経験していると思います。私はそんな方々から「粗探しをされる」「自分のスキルを馬鹿にされる」といったネガティブな感想や、「何をレビューすればよいか分からない」「ただの感想文になってしまう」といった相談をよく受けました。

今回はそうした声をもとに、私自身のコードレビューに対する気概を、技術者目線より高い視点から抽象的に俯瞰することを目指し、noteの記事としました。

なぜコードレビューをするのか、それは最終的に快適に業務を進めるためだと解釈しています。なぜならば、不具合の多いアプリがずっと放置されるような環境は、会社としての体制に間違いなく問題があり、ひいては会社自体の存続にも関わってくるためです。

今回の内容は具体的なコードレビューの手法ではなく、抽象的すぎてじゃあ実際どうすればよいのか、といった意見もあるかとは思います。そこに臨むまでの気概のひとつとして、参考になれば幸いです。

Discussion