普段コードを触っていると、ここ直したいなぁと思う瞬間がある。
その直感にまかせて、機能追加のついでに大きめのリファクタをやってしまったことがある。
いざPRを出そうとしたとき、「このPRは何をしているのか」をうまく説明できなかった。
機能の追加なのか構造の整理なのかが、自分の中でも曖昧になっていた。
機能追加とリファクタを同じPRに入れると、レビュアーは「この変更は何のためにあるのか」を読み解きながら見ることになる。
不具合の原因を切り分けにくくなるし、revertもしづらくなる。
変更を分けて、1つの理由で説明できるようにした
この経験から、変更には2種類あることを意識するようになった。
- 振る舞いの変更
外から見た動作が変わるもの。機能を追加するとか、バグを修正するとか - 構造の変更
動作を変えずにコードを整理するもの。クラスを分割するとか、依存関係を整えるとか
この2つは変更理由が違う。
なので、人に見せる前には「この変更は、1つの理由で説明できるか」「このPRは○○のためのPRです」と一文で説明できるかどうかを見直すようになった。
なぜ今これをやるのかを書くようにした
ただ、変更の意図が1つに絞れていても、それだけではレビュアーに渡せる情報が足りないなと感じるようにもなった。
- 「なぜ今この変更をするのか」
- 「他の方法ではなくなぜこのアプローチを選んだのか」
が書かれていないと、レビュアーは同じ問いをゼロから考えることになる。
別の設計案はないか、このタイミングでやる必要があるのかを一から探索する。
その探索は、PRを出した自分がすでにやったものと重複する。
だからPRには変更の理由に加えて、検討して選ばなかった選択肢とその理由も書くようにした。
レビュアーの検討コストはゼロにはならないけど、同じことを探索するコストは減らせる。
書く過程でなぜこっちにしたんだっけを自分でも問い直すことになるので、判断が甘かった部分に気づくこともある。
後から変更するときの手がかりにもなる。
あるべき姿を先に決めてから、分割を考える
また、実装を始める前にあるべき姿を考えるようになった。
以前、リファクタをしていたら途中で別の箇所の問題が気になって、ついでに直しておこうと混ぜて実装を進めたことがある。
その際、「これはもともとやろうとしていたことに寄与するのか」「今これをやる理由はあったのか」という指摘をもらった。
改善する行為自体はプラスだとしても、その時の自分は「なぜ今これをやるのか」が説明できなかった。
ゴールが決まっていないと、途中で気になったものを拾い続けてしまう。
あるべき姿を先に決めておけば今回のスコープ外と判断できる。
今は変更に取り掛かる前にゴールを先に決めて、そこから逆算して問題をどう分割するかを考えるようにしている。
「この変更は何のためか」を自分で言えるようになった
変更を分けるようになってから変わったのは、「変更の目的を自分で説明できるかどうか」を意識するようになったことだと思う。
以前はついでにやるか後回しのどちらかで、どちらも変更の意図やタイミングがあいまいなまま進んでいた。
分けて考えるようになってから、「これは構造の変更として別でやる」と判断できるようになった。
「この変更は何のためか」の観点を持つことで、一つ一つの変更に対してちゃんと目を向けられるようになったと思う。