不要なコードを見極めて削除するポイント
この記事は カオナビ Advent Calendar 2023 4日目の記事です。
はじめに
皆さんはコードを消していますか??
不要なコードが残っていると後から技術的負債となって重くのしかかってきます。
そこで今回はコードを書くより、消す方が好きな私が不要なコードを削除することについて
日頃から行っている削除対象の見極めるポイントを書いていこうと思います。
どんなコードが不要なのか
まずはどんなコードが不要なのかを知らないと消せないですね。
一応、私が考えでは不要なコードは次の通りかと思っています。
未使用な変数、定数、メソッド、関数、クラス
わかりやすいですね。
使っていないコードは不要なコードと判断できます。
コメントアウトしたコード
極端な例ですが、次のようなコメントアウトしたコードは不要ですね。
// 初期値を1 -> 2に変更
// $a = 1;
$a = 2;
意味がわからないコメント
コメントアウトしたコードに近しい内容ですが、
次のような例だと当初は正しいコメントでも、修正を行なった際にコメントの修正が漏れた瞬間に意味が不明になります。
そのようなコメントはサクッと消してあげる方が良い場合もあります。
もしくは正しい内容に変更してあげてください。
// 2つの変数を足す
$c = $a - $b;
デッドコード(到達不能なコード)
たとえば次のコードだと、
引数に型指定をしているので、int以外はそもそも指定できないので、is_nullの判定は不要ですね。
function plusOne(int $a): int
{
if (is_null($a)) {
return 0;
}
return $a + 1;
}
不要なコードはなぜ生まれるのか
なぜ不要コードが生まれるのか?って以前聞かれたことがあります。
色々と理由はあると思いますが、その時は私は次のようなことを答えました。
いくつか書いていますが、概ねは2パターンだと思います。
必要と思ったけど、実際は不要だった
たとえばこんなお話があります。
A、B、Cと3つ作ります。最初にA、BをリリースしてからCを作ります。
A、Bの開発中にCで使う処理まで作っておいたけど、A、Bのリリース後、Cの開発は止まってしまった。
先行して作っておいたCの処理は残されたままになり、不要なコードが誕生しました。
悲しいですが、不要なコードはこのように生まれます。
何かの機能追加で初期に作ったけど、開発中に不要になるが消し忘れる
1つ前と同じような状況ですね。
最初は使われていたけど、開発中の仕様変更などで使われなくなった際に消さずに残り続けることがあります。
不具合修正や機能改善で処理を書き換えた際に前の処理が残り続ける
前2つと一緒かもしれないですが、結構な確率で放置されます。
実際に不具合修正や機能改善をやっている時にコード削除まで考えないでしょうからね。
サービス提供をやめた機能のコードがそのまま残る
長くサービスを続けていくと、使われない機能や時代に合わない機能も出てきます。
※たとえば今の時代にガラケー向けの機能は使われないし、いらないですよね。
この場合、特定の画面から機能は消えることになると思いますが、裏ではコードが残り続けていたりします。(もちろん消してくれる場合もありますよ)
残り続けると、先ほどの例だと、
ガラケーからのアクセスなのか判断する処理は動き続けたりします。
こういういった処理が多いとパフォーマンスをじわじわと悪くしていく原因だったりします。
なぜコードを消さないのか
一番の理由は、
怖いからでしょうね。
実際に消すとどこに影響があるかわからない場合が多いです。
なので、先ほどの不要なコードが生まれるところに書いた「処理を置き換えた後に放置される」理由もコレだと思います。
消すと何が嬉しいのか
まずは、機能の追加、改修、修正のどれをやるにしても既存のコードは調べる必要があります。
そこで使われているのかわからないコードまで調べるのは意味がないので、そういうコードを事前に消しておくことで工数削減になります。
また、言語やフレームワークなどのバージョンアップの際の修正対象を減らすことも目的になります。
PHPのバージョンを上げる際に廃止された関数、非推奨になった関数を使われていた場合に未使用なコードも修正を行う必要があります。
これを事前にコードを消しておけば、修正対象を減らすことが可能ですね。
最後にムダに動くコードの存在でパフォーマンスが悪くなるなら消すことがパフォーマンスを良くしましょう!!
これはサービスを利用している人にとって嬉しいですし、提供している側も嬉しいはずですね。
コードの削除の進め方
ここからは実際に削除までの道のりを書いていきます。
不要なコードを探す
コードの削除で一番大事な部分ですね。
どのように探して、本当に使われていないか見極めのポイントは次のような感じです。
静的解析ツールの結果
PHPStanはレベル4からデッドコードがあれば指摘してくれるので、
指摘された箇所を1つ1つ確認し、本当にデッドコードなのかを見極めて削除対象を見つけていきます。
コードカバレッジ
テストコードがあればコードカバレッジを計測しカバレッジが0%のクラス、もしくは、メソッド、関数を確認し未使用なのか、単純にテストが未作成なのかを見極めて削除対象を見つけていきます。
ただし、未使用だけど、テストコードがあるためにカバレッジが100%だったりすると探し出せないので0%以外でも削除対象が存在しているって思っておくことが大事だったりします。
廃止した機能のワードで検索
廃止した機能のコードならネームスペースやクラス名に機能名が入っていたりすると思うので、
機能名でgrepして探し出します。
見つかったコードが廃止した機能だけで使われているのかを見極めて削除対象を見つけていきます。
アクセスログから探す
利用しているAPIや画面のURLがアクセスログに残ると思います。
つまり、利用していないAPIや画面のURLはアクセスログには残らないので、
特定の期間でアクセスがないURLを探します。
該当するURLがあれば、APIや画面で利用しているコードをgrepやコードカバレッジを確認し、削除対象を見つけます。
コミットログから探す
数年前から変更が入っていないコードに関しては、次のケースに該当することが多いです。
- 必要と思ったけど、実際は不要だった
- 置き換えた前の処理が残り続ける
そういったコードがあれば、コードカバレッジを確認したり、grepして利用箇所を見たりするといいかと思います。
目視で見つける
コメントアウトされたコード、意味がわからないコメントについては目視で見つけていくしかないかなって思います。
ただ、これまでの探し方を実践していけば自然とたくさんのコードを見る機会があるはずなので、その時に見つけた箇所についてはTODOコメントを残しておきます。
こうすれば後からコメントを直したり、削除したりすることが可能かと思います。
コードの削除
いくつかの手順から削除対象を見つけたら実際に削除します。
削除の方法としては2パターンあると思っています。
- 削除する
- コメントアウトする
1については、
本当に削除するだけです。簡単ですね。
削除対象を探す時に本当に使われていないのか見極めているのであれば恐れることはないです。
もし、削除したコードが使われていた場合
バージョン管理されている環境であれば最悪元に戻せば済むわけですからね!!
2については、
削除対象が本当に使われていないのか見極めきれなかった時のみだと思います。
なぜなら、不要なコードの定義にコメントアウトしたコードがあったと思いますが、まさにそれに該当するからです。
なので、この方法は新たな不要なコードを誕生させることになるので、極力実施しない方がいいかと思います。
コードレビュー
コード削除した後は有識者にコードレビューを依頼します。
サービスに長く関わっている人ならこちらが不要なコードと判断した場合でも、ここで使っている、追加でこちらも削除できるなど教えてくれる場合もあります。
テスト
未使用コードであれば、どこからも利用していないのでテストは不要な場合もあるかと思いますが、
廃止した機能のコードやデッドコードなどは既存コードから一部を削除する場合もあるので、既存に影響が出ていない確認するテストを実施する必要があります。
テストの方法としては、ユニットテストやE2Eテスト、手動テストなど、
すでにあるテストを活用してもいいし、新規で用意してもいいかと思います。
とにかく、既存に影響がないことを確認します。
リリース
テストで問題なければ、本番環境にデプロイして、master(main)ブランチにマージして完了です。
しばらく本番環境のログなどを監視して何も起きなければ不要なコードの削除が完了です。
まとめ
不要なコードに対しても考え方や探し方、削除の手順を書いてきました。
実際の削除については機能追加などと変わらないと思います。
つまり、コードの削除と機能追加は同じことなんです!!
なので、怖がらずに不要なコードを見つけたら削除して行ってください!!
それが技術的負債の解消にもつながりますし、言語やフレームワークなどのバージョンアップも楽することができると思いますよ!
Discussion