不慣れなコードをリファクタするために
不慣れなコードベースをリファクタするために、どんなことをやって有効だったかをメモします。
動いているサービスは偉いことを覚える
リファクタリングが必要と直感したとして(それが正しいか否かにかかわらず)動いて顧客に価値を提供し、売り上げを上げているシステムのコードベースは偉いです。これを魂に刻むことが第一歩だと考えます。どんなに不合理なコードに感じても、それがユーザに価値を提供していることは間違い無いです。直感よりも実績を尊重して敬意を払いましょう。
既存のコードベースを作り上げたときより、今のほうが既知の文脈が大きいことを理解する
既存のコードベースは偉いですが、それを運用したりサービスの要求が進化した結果、既存のコードベースが今最高に欲しい状態になっているとは限りません。一般的には今の文脈では最適な状態では無いでしょう。これは既存のコードベースを作り上げるときよりも、その結果を受けた未来を生きている我々の方が大きな文脈を所有しているからです。過去の開発者からしたら今の僕たちはズルをしているような状態です。もし今の文脈でもコードベースが最高な状態なら、コードベースが晴れて枯れたことになるのだと思います。ツールの開発ではそういうことがあるのかも知れませんが、事業としてのサービスを提供するためのプロダクトではそんなことは怒らないでしょう。
機能要件を理解する
ここまではプロダクトの実装の話をしてきました。ところでプロダクトはサービスを提供するための部分的なリソースに過ぎません。サービスを提供して利益を得るためにプロダクトを開発・運用しているだけです。プロダクトのことだけ考えていては目的を見失います。
今のプロダクトが見据えていた目的と、これからのプロダクトが見据えるべき目的を理解する必要があるでしょう。これらを理解するためにはサービスとか事業の方針を理解する必要があり、その結果としてプロダクトの要求・要件に落とし込むことが開発者には求められます。既存コードをリファクタすることの目的は、この変化する要求に対応し、要件を改正し、結果としてコードベースを自然に改正できる状態にすることです。
そういうわけで、当時の機能要件とこれからの機能要件を理解することを目的にすると良いでしょう。
コードベースを全部理解する
既存のコードベースが叶える機能要件が文書に落とし込まれていれば良いのですが、そんなことはないでしょう。残念ながら信頼できるのは動くコードだけです。もちろん参考になるドキュメントはあるはずですが、それが本当に実現されているかとか、それがどのように実現されているかを理解するためにはコードベースを理解する必要があります。あるいは、叶えるべき機能要件と実際の実現の間に乖離がある場合(多かれ少なかれあるでしょう)、その際を認識するためにやはりコードベースを理解する必要があります。
コードベースを理解するためには以下を行えます。
- コードを読む
- テストを読む
- それらを編集して動作をみる
コードを読むのは説明不要でしょう。コードを読んで完全に理解したらもちろんコードベースを完全に理解できます。テストは通ることが保証されているプログラムの実行例です。コードの重要な振る舞いを読み取れるはずで、コードベースの理解に役立つでしょう。コードやテストの一部を変えたらどうなるだろう、と疑問を投げかけることも重要です。こういう実装をしないのはなんでだろう、とかこういうケースには何が起きるのだろう、とか思ったときには実際に試してみればいいのです。それはコードやテストの編集で実現できます。
コードベース理解を加速するための改善を加える
勉強をするときって「これはきっとこういうことだろう」という仮定を立てて、それが正しいことを腹落ちさせて、それを元に次の概念を理解しにいくものです。コードベースを全部理解することも同様のプロセスをたどります。つまり以下を行うわけです。
- 仮説を立てること
- それが正しいことを腹落ちさせること
- それを元に次の概念を理解する足掛かりにすること
勉強では先生に質問したり、演習問題を解いたりノートにまとめたりしてこれらを行います。一方でソフトウェアのリファクタリングではコードベースの修正とテストの実行でこれを行うことができます。
- 仮説は勝手に立ててください
- それが正しいことを腹落ちさせるために、コードの修正やテストの追加をしましょう
- それを元に次の概念を理解するためには、うまい抽象化をコードですればいいだけです
このサイクルを素早く行えるようにする
このサイクルを行うために、開発環境を整えましょう。AIツールを導入する、テスト実行を早くする、コメントを充実させる、変数名を修正するなどなど。読みやすいコードベースに変えていくということです。