はじめに
コードは書くより読む時間の方が圧倒的に長い。
この格言は、レガシーコードの保守・追加開発に関わるたびに実感する。
スパゲッティコードが酷すぎて、ゲロ吐きそうな日々を送っている。。。
flg2 や checkXXX3 といった意味不明な命名、迷宮入りしたネスト、広すぎるスコープ。
もはや仕様も意図も分からず、調査・改修・レビューが完全に地獄化している。
そんなソースを見るたび、改めて痛感する:
- リーダブルコードは“美学”ではなく、業務効率に直結する改善策
- 可読性の向上は、あらゆる工程のコストをまとめて削減できる最もコスパの高い投資
- 「他人が読んでもすぐ理解できる」という観点では、コードに限らず設計書やコメント、バージョン履歴に関しても同様
※本記事では、文献で学べるリーダブルコードの基本は省略し、
「最低限これだけは守ろう」という実務視点のポイントに絞って紹介する。
対象者
- 初心者〜3年目くらいの方:可読性が悪いと言われたことがある方
- 中堅でレビュー指摘が多い方:何が悪いのか分からない方
- レビューアの方:工数を鑑みて指摘せず、動作すれば良いという思考の方
レガシーコードでの保守、追加開発の課題
-
複雑/肥大化
長年の改修でのコードの複雑化、巨大な関数やクラス、複雑なネストや条件分岐。。。
軽微な修正でも多大な調査工数が必要になる。 -
属人化
特定の担当者や前任者しか分からないコードが増え、改修や引継ぎが困難。 -
ブラックボックス化
ドキュメント不足や不備で、仕様や改修経緯が分からず、コードの意図が読み取れない。 -
履歴追跡が困難
バージョン管理していても、履歴コメントが曖昧で、変更意図が分からない。
これらは、調査・修正・レビュー・テスト、全工程で工数を押し上げる要因となる。
最低限これだけは守ろう
-
命名は「何のための変数か」が分かるように
flg2→isValidUser、checkXXX3→hasPermission()など、役割が伝わる名前にする。
⇒変数名で役割が推測できるので、調査・レビューが圧倒的にラクになる。 -
ネストは浅く、早期リターンで抜ける
条件分岐が深いと読みづらいため、ガード節で早めに抜ける構造にする。
⇒処理の流れが一目で分かるようになり、読解・修正・テストの工数が減る。 -
変数のスコープは最小限に
クラス全体で使う必要がないなら、ローカルに閉じる。
パラメータで渡すなど、副作用を減らす。
⇒予期せぬ影響を防げる。テストしやすく、バグ調査が早く終わる。 -
機能分割する
1つの関数に、複数の目的・役割を含めない。
「データ取得」「変換」「表示」など、処理の単位ごとに関数を分ける。
⇒可読性が上がり、テスト・再利用・レビューが効率化される。 -
同じ処理は共通化する
条件分岐や変換処理など、繰り返し出てくるロジックは共通化して1箇所で管理する。
⇒修正漏れを防ぎ、テスト工数を減らせて、保守性・変更耐性が上がる。 -
ソースコメントは処理の意図を明記
1行毎に「~の場合」「~を設定」ではなく、ブロック単位で「~の場合に~なので~する」など処理の意図・目的を残す。
⇒コメントは過信は禁物だが、調査、レビュー工数が確実に減らせる。 -
履歴コメントは「なぜ」修正したのかを明記
Gitログに「~対応」ではなく、「~対応に伴い、~するよう修正」など、変更背景の理由・目的を残す。
⇒変更背景が追えるので、再発防止や仕様理解がしやすい。 -
おまけ(性能観点)
ループ内でファイル・DBアクセスは著しく遅くなるため、極力避ける。
⇒パフォーマンス劣化を防ぎ、ユーザーの体感やバッチ処理の安定性が向上する。まとめ
負の遺産を残すと、後続工程は永遠に工数が膨らみ続ける。
調査・修正・レビュー・テスト、保守、すべての工程で負荷が積み上がる。「工数がない」「納期が厳しい」からといって、実装やレビューで妥協したツケは、必ず誰かが将来払うことになる。
だからこそ、実装者もレビューアも、今一度リーダブルコードの概念・重要性を見直してほしい、と思う今日この頃。。。
「誰でも読める」という概念は、全ての工数を軽くする!!
を肝に銘じて自分も業務にあたりたいと思います。