🐣

私達がプロジェクト参画直後に「リファクタリングしたいなぁ」と思ったら考えたいこと

2023/05/21に公開

はじめに

このポエムを執筆する少し前から、"リファクタリング" や "プロジェクト参画直後" といったワードが SNS のエンジニアクラスタで話題となっていました。

とある記事がきっかけとなっていたのですが、その記事で語られていた内容を発端に様々な意見が SNS 上で発信され、多くの立場からの意見を交換し合うことがトレンドとなっていました。

筆者もその記事を拝見させていただいたのですが、現在の自身の考えを言語化・発信し、意見交換を行いたいなと思ったので筆を執りました。

この記事を最後まで読まれた方は、感じたことや意見などをぜひコメントとして残してください。筆者を含めた皆さんの価値観アップデートの助けになります。

ぜひ読んでほしい推奨読者

  • プロジェクトへ参画したばかりのエンジニア職の方
  • 関わっているプロジェクトのコード品質に疑問を持っているエンジニア職の方
  • リファクタリングの提案・進め方に関して迷いを持っているエンジニア職の方
  • エンジニアがリファクタリングを提案する理由を知りたいマネジメント職の方

なぜエンジニアはリファクタリングをしたくなってしまうのか

エンジニアがリファクタリングをしたくなるパターン。筆者はいくつかの背景があると考えています。

  1. 連綿と受け継がれてきたコードの保守性が低下している
  2. 熟練者が見たときに、改善点が多く存在している
  3. 自身が快適だと感じるコードや設計と相容れない
  4. コードが理解できず、自身の理解できる領域まで落とし込みたい

それぞれのパターンについて、より詳細に言語化します。

連綿と受け継がれてきたコードの保守性が低下している

これは一番わかり易いパターンだと思います。長い期間の開発を続けていくにあたり、0 → 1 のフェーズでは顕在化していなかった問題が表出してくる場合です。

言うなれば、コード資産のポートフォリオが悪い状態になっており、悪貨が良貨を駆逐し始めている ということですね。これには「利益を最大化するためにあえて悪貨を受け入れていた」場合も「ポートフォリオ内に悪貨が含まれていたことに気づかなかった」場合もあります。

日々顕在している問題を放置し付き合っていくリスク。それが開発チームのリスクテイクの許容範囲を超えてしまっており、職務をこなす上で強いストレスとなっているため、「どの部分がどういった問題を引き起こしているのか、なぜ解決したほうがいいのか」という背景も開発チーム全員が飲み込みやすいです。そして「チーム一丸となって解決しよう!」という流れを生み出しやすいです。

このパターンの場合、「手遅れになる前にどうにかする」動きができるのか、「時すでに遅しなので、新規開発を一旦止めてまでリファクタリングを行わなければならない」段階なのか、でビジネスへの影響が大きく変わります。後者はプロダクトの成長を止めてまで行わなければならないため、事業フェーズによっては大打撃にもなりかねません。

熟練者が見たときに、改善点が多く存在している

エンジニアは(大なり小なりの程度はありますが)0 → 1 を生み出すフェーズに関わることが多く、そしてそのフェーズに関わる際の力量(実装力・設計力)は正直に言ってバラバラです。高い技術力と経験値を持ったエンジニアがガツガツと作り上げる場合もあれば、新しい技術を試しながら Example にほぼほぼ近しいコードを書くことも多々あります。

そして後者の場合、その技術をある程度理解・利用してきた技術者から見ると、

  • 最適化されていない
  • 言語特性をうまく活かせていない
  • そもそも設計(品質・保守性・拡張性などなど)が良くない

というように 見えてしまいます 。これは技術的力量の勾配が存在する以上、仕方のないことだと思います。

そして、それらに対してウズウズとしてしまうのもエンジニアの性です。新しいものに触れ、生み出し、出荷している立場上、「いかに効率よく開発・出荷するか」「いかにバグのない高品質のプロダクトを実装するか」は職務至上命題であり、その教えや性は脈々と受け継がれています。

エンジニアは誰だって、「少しでも触れたらバグが発生するガラスのようなコードが溢れている」「過度に冗長すぎてサクサクと開発できない」環境には関わりたくありません。なぜなら、自身のコミットがプロダクトに対して良くないインパクトを与えてしまうかもしれない、という恐怖が常につきまとい、ストレスフルになってしまうからです。

エンジニアは、それらを解消するためにリファクタリングを行い、上記の解消を少しでも行おうという意識がとても強い職種なのです。

このパターンに関しては、高い技術力や経験値を存分に発揮して、どんどん改善を行ってほしい という依頼を受け、役割が与えられることがあります。そうなった場合は、改善点をしっかりと伝え方針を示し、ガンガン改善していきましょう。それがあなたに求められているコミットメントなのですから。

自身が快適だと感じるコードや設計と相容れない

このパターンもあるあるだと思います。筆者もよく陥りました。そして、どちらかというと否定的な意見を生むことの多いパターンです。

今まで携わってきた様々なプロジェクト、個人開発、勉強…。それらの経験から、エンジニアは各々 "ベストプラクティス" や "アンチパターン" を確立しています。

そして、新しいプロジェクトにアサインされ、そのコードを見てみると…、なんと、自身のベストプラクティスとは程遠い設計・構想になっているではありませんか!自身が快適に感じる思想とは全く異なる考えで組まれているコードを見て「これは改善せねば!」と躍起になることもあると思います。

これを筆者は「子供部屋を勝手に掃除するオカン現象」と名付けています。みなさんも子供・オカン両方の立場になった経験があるんじゃないでしょうか。

さて、この「子供部屋を勝手に掃除していしまうオカン」には問題点があります。

  • オカンが 自身の価値観のみ を判断基準にしてしまう
  • オカンが「なぜ散らかっているのか」を想像せず、勝手に 掃除を始めてしまう
  • オカンにとっては不快 でも、子供にとっては 快適 であることもある

これらを順番に見ていきましょう。

オカンが "自身の価値観のみ" を判断基準にしてしまう

これはこのセクションの冒頭に話したエピソードです。「(自身の)ベストプラクティスに則っていない!絶対にこうした方がいい!」という信念のもと、リファクタリングを行おうとしてしまうんですね。

確かに、その人の経験上はベストプラクティスであり、その人は何度もその方法によって救われてきたことでしょう。そして、それは チームの合意を得た上で 取り組んだはずです。「連綿と受け継がれてきたコードの保守性が低下している」問題に対応したときに合意を得たり、日々のコードレビューで受け入れてもらったりと様々でしょう。

しかし、それらのように自然な流れではなく、いきなり「こうした方がいい!」という気持ちのみで進めてしまった場合はどうでしょう。他のエンジニアはそのプラクティスのメリット(そしてデメリットも)をうまく咀嚼できていないのに、着々と進んでいってしまう掃除を見てどう思うでしょうか。

オカンが「なぜ散らかっているのか」を想像せず、"勝手に" 掃除を始めてしまう

あなたが今いる環境は、前にいた環境とは違います。プロジェクト規模、携わる人や役割。なぜそのプロジェクトが立ち上がったのか。ぶつかってきた困難をどのように解決していったのか。それらは、あなたがいたところと同じ部分はほとんどありません。

その背景をキャッチアップできていない段階で掃除を始めようとしてしまうと、「なんで部屋を掃除しようとするんだろう…」という(ある種マイナスな)感情をチームに抱かせてしまうことになるかもしれません。

また、実は子供が「掃除をする計画を立案していた」場合もあります。「何を使って掃除をしようか」「どこから掃除をしようか」「どうやって掃除をしようか」と頭を悩ませている最中だったかもしれません。

まさにその瞬間、オカンが入ってきて掃除を始めてしまいます。これでは、掃除を計画していた子供にとっては(言い方は良くないですが)興が削がれてしまいます。「これはここに置いた方がええで!」「もうこの服は小さくて着られないから捨てちゃうわよ!」「これは大事な思い出だから捨てずに取っとき!」と、断捨離や整理まで始めてしまうのです。

その行為は、子供の「ベッドに近い位置に合ったほうが便利だったのに…」「小さいかもしれないけど、お気に入りの服だったのに…」「写真やアルバムとして残してあるし、置き場所に困っていたからクローゼットに仕舞おうと思っていたのに…」という考えを軽んじ、(強い言葉を使ってしまうと)否定することにもなりかねません。

オカンにとっては不快でも、子供にとっては "快適" であることもある

これは心理的な働きが関わってくるところもあるので語るのが難しい部分ではありますが、人間には「遠い将来の利益よりも目の前の利益を重要視する」というバイアスが働いています(これを 現在価値バイアス というらしいです)。

人間だれしもが「未来のことよりも現在のことで満足感を得たい」という心理が働きます。なんとなく「いつか痛い目を見そうだな」と思っていても、その "いつか" より "今" に強い価値を見出すのです。そして、みんなその状況に慣れてしまいます。

古くからプロジェクトに関わっているメンバーはこの心理になっている可能性があり、今の環境を「快適である」と感じていることもあるのです。

コードが理解できず、自身の理解できる領域まで落とし込みたい

これは厳密には "リファクタリング" の定義からは外れてしまいますが…。

これは筆者自身も行うことがあります。初めて読んだコードが自身にとって複雑度が高く、なかなか咀嚼しきれないときがあります。その場合、自身が理解できる形となる変更を行い、その最中や完了後に改めて理解を深める、という方法を取ることがあります。"理解・分解・再構築" のプロセスを踏むわけですね。

このパターンには、いくつか議論となりやすいポイントがあります。

  • 理解度を深めるためだけにコードを改変する是非
  • 理解できないなら分かる人に質問すればいい、という意見の是非

まず「理解度を深めるためだけにコードを改変する是非」についてですが、筆者は良い面と悪い面があるかなと考えます。

良い面としては、

  • 新しく参画した人が理解しやすいコードになる(副次的に、人数に対してスケールしやすいコードになる)
  • 整理されることにより、新たな改善点が見つかる可能性がある

悪い面としては、

  • 既存メンバーにとってはリファクタリングする意味がほぼない
  • 最適化されていた(と思っている)コードが最適でない形になる可能性がある

です。これらの良い面・悪い面をチームとしてどのように捉えるか、に左右されやすいポイントだなと思います。

次に「理解できないなら分かる人に質問すればいい、という意見の是非」についてですが、これは チーム全体や既存メンバーの練度 によって大きく差が出るポイントだと考えます。

既存メンバー全員が「すべての仕様や実装を熟知し」「それをしっかりと新規参画者に伝えることができる」ならば、問題なく機能すると思います。しかし、これらが少しでも熟練していない場合、「聞いても分からなかったので自分で理解するしかない」という感想を生んでしまい、このような改変を行わせてしまったり、最悪の場合は 分からないままそのコードに手を加えなければならなくなってしまう という状況を作り出してしまいます。そうなると、せっかく長持ちするように工夫してきた コードの寿命を縮めてしまう ことに繋がってしまいます。

エンジニアは自分の触るコードを理解してナンボです。そこが大きく阻害されてしまうことは避けなければならず、しっかりと理解するために分解をすることも多々あるのです。

参画直後のリファクタリングは悪か?

では、参画直後のリファクタリングの是非について考えをまとめます。

筆者は上記のパターンのうち、「熟練者が見たときに、改善点が多く存在している」パターン以外ではアンチパターンになりうる可能性が高い、と考えています。

「連綿と受け継がれてきたコードの保守性が低下している」パターン

まず「連綿と受け継がれてきたコードの保守性が低下している」場合、それはもはや開発チームのみの課題ではなく、立派な 事業課題 です。事業課題である以上、開発チームだけでなくプロダクトオーナーや更にその上のレイヤーに属する人たちも把握しておかなければならない問題になります。

なので、提案する際には「関わる全てのレイヤーの人たちにアラートを上げる」ことまで責任を持って行わなければなりません。果たして、参画したばかりのメンバーにそれほどのことを行える裁量や判断を任せてもらえるでしょうか。

残念ながら、(筆者の社会人経験上では)そのようなことは滅多に任せてもらえません。なぜかというと、それは非常に高度な 政治的問題 を発生させるからです。ビジネスへの影響、低下するであろう利益の補填方法、顧客への説明責任、その他色々なことが一気に押し寄せてきます。よほど強い発言力のない限り、事業計画に強いインパクトを与える提案は通らないです。

また、「プロダクトオーナーが現状の負債を受け入れている事業判断をしている」という場合もあります。「事業利益を直接的に生み出さないきれいなコードを作る時間」よりも、「汚くとも変わらず利益を生み出し続けるコードをもとにプロダクトの機能を開発する」ことを選択していたりします。その場合、現状価値バイアス を大きく覆すほどの説明を行わなければなりません。これは大変な労力とストレスのかかる行為です。しかし、これを乗り越えなければ事業判断は覆りません。

なので、参画直後にこのパターンの提案を行おうとしている場合、それ相応の覚悟を持って事に当たらなければなりません。一番小さい発言力で、大きな組織に立ち向かわなければなりません。そして、それを見事成し遂げられる人は非常に少ないです。なので、自分としては強くおすすめはできないです。

「熟練者が見たときに、改善点が多く存在している」パターン

このパターンに関しては、どんどん改善提案を行っていいと考えています。

参画に賛成した人たちは、あなたの役割としてその動きを強く期待しています。しっかりと提案を行い、コードとプロダクトの品質を高める役割を全うしましょう。

ただし、この場合でもきちんと「なぜこのような実装になっているのか」という背景の理解は必須です。普遍的に提唱されている改善箇所の修正提案なら問題ありませんが、経験則からのベストプラクティスとなると、少し事情が変わります。

そのコードベースになったのには必ず理由があります。その理由を知らないまま自身の経験則のみで押し通ることは、既存メンバーのベストプラクティスを軽んじる ことになります。

「自身が快適だと感じるコードや設計と相容れない」パターン

このパターンの場合、少し前に触れた「勝手に子供の部屋を掃除するオカン」の問題点が表出します。「なぜこのような実装になっているのか」という背景を理解する までは悪手です。

「コードが理解できず、自身の理解できる領域まで落とし込みたい」パターン

このパターンの場合、いきなり「よく分からなかったのでリファクタリングしてみました!」とすることは避けたいです。なぜなら、リファクタリングによって生まれた差分は、既存の開発に対して 必ずしも良い影響を与えるとは限らない からです。

このパターンに陥りそうなときは、まず 既存メンバーに質問しまくる ことをおすすめします。「どういうロジックなのか」「なぜこのように組んだのか」は、実際にコードを書いた既存メンバーが一番詳しいです。

もし質問に関する答えが不明瞭であったり、そもそも質問に回答してくれない場合、チームとしての練度が低いことが考えられます。その場合は、既存メンバーの理解度を確かめる意味でも 分解・再構築した結果を提出 することを行ってみましょう。この段階において、コードの理解を達成する手段 としてリファクタリングを行うことを検討するのは、筆者としてはアリです。

提出方法は「ドキュメントにまとめる」でも「実際にリファクタリングした結果を Pull Request として提出して様子を伺う」でもいいと思います。Pull Requst の場合は既存メンバーにとって不要であれば取り込まずに Close するということになるでしょうし、ドキュメントであればこのあとに参画したメンバーの理解の一助に必ず役立ちます。

どうすればリファクタリング提案が通りやすくなるか?

これは筆者の考えを一言でいうと、「"勝手に掃除をするオカン" になるのではなく、まずは "掃除を委託されるプロ" になることを目指しましょう」です。

"掃除のプロ" は顧客の私物を勝手に処分しませんし、物の配置も大きく動かしたりはしません。あくまで掃除するのは「誰が見ても汚れている」と判断できる箇所です。

そういった掃除をこまめに繰り返していると、「よくよく考えたらこれは不要だな」「きれいになった分、部屋が広くなったからスペースを有効活用したいな」という気持ちが顧客が思い始めます。そうなったときがチャンスです。あなたの経験からベストと思える提案をしてみましょう。断捨離を一緒にしてみたり、スペースの活用法を提案してみたり。顧客のペインに寄り添いながら、最高の改善案をともに実現しましょう。

まとめ

今回は、筆者の頭の中にあった「リファクタリングをしたくなる背景」と「リファクタリングは悪か?」、「どうすればリファクタリングが通りやすくなるのか」を言語化してみました。

このポエムが皆様の価値観のブラッシュアップ、意見の種となれば嬉しいです。

この記事がいいなと思ったら、「いいね」と「フォロー」をぜひお願いします!


参考リンク

GitHubで編集を提案

Discussion