皆さんは謎のコードを見たことがあるでしょうか?
例えば「何故か同じような処理を何回も実行している」「何かしらデータの更新をしているが、そのデータの参照箇所が見当たらない」といったようなものです。
エンジニアとして活動している人であれば、思い当たることもあるでしょう。
(まだそんなコード見たことないという人も、そのうち遭遇すると思います)
これらの謎のコードはどうして作られるのでしょうか?
エンジニアのスキル不足やケアレスミスでそうなったのでしょうか?
もちろんそういった単純な理由のケースもありますが、実は優秀なエンジニアが実装していたにも関わらず謎のコードが作られてしまうこともあるのです。
そしてそのような場合には、謎のコードが作られてしまうまでの複雑な経緯、つまり「コードの歴史」とも言えるものがあるのです。
という訳で今回はそんなコードの歴史について解説していこうと思います。
コードの歴史が積み重なる要因
一言に「コードの歴史」と言っても、社会の歴史と同様にその成り立ちは様々です。
いくつかよくある要因を紹介していきます。
仕様の変化
コードが最初に書かれるとき、当然ながらその時の使用に基づいて書かれます。
しかし時間の経過に伴いユーザーのニーズが変化したりプロジェクトの方針が変わったりで仕様が変わるのはよくあることです。
仕様が変わると当然コードの修正も必要になります。
そしてコードを修正する際に、「元の仕様では必要だったが、新仕様では不要になった処理の消し忘れ」「元の使用では最適な設計だったが、新仕様では冗長な設計になってしまった」等の要因でコードに歴史が生まれてしまいます。
僕がよく見かけるのは、当初はとあるデータが必要だったので専用にDBテーブルが作られたものの、後々不要になり謎のDBテーブルとその参照だけが残ってしまった、みたいなパターンです。
普段であれば、不要になったDBテーブルまで消すでしょうが、スケジュールがカツカツな時は見逃されがちです。
技術の進化と制約
コードが書かれた当初の技術的な背景も歴史を形成する一要素となりえます。
使用可能なツールやライブラリ、あるいは会社やプロジェクトの方針等で、最適解とは言い難いコードになることはよくあります。
または開発・運用期間の長いプロジェクトで、当初は最新の技術を活用していたものの、時間とともに古くてパフォーマンスの悪いコードになってしまった、なんてパターンもよく見かけます。
僕がよく見かけるのは、使用しているライブラリのバグを避けるため、仕方なく本来は不要なはずの冗長な処理を書かざるをえなくなったパターンです。
特にニッチな機能を提供するライブラリ等の、選択肢が少ない技術領域でよく見かけます。
バグ修正の積み重なり
プロジェクトの開発・運用中に発生するバグ修正もコードの歴史に大きな影響を与えます。
バグ修正は根本原因をきれいさっぱり解決できるものばかりではありません。
時にその場しのぎでの修正対応を余儀なくされることもあり、その修正対応が次のバグのきっかけになって…と負のループの始まりになる場合もあります。
僕の経験上、複数人が分担して実装しなければならないような複雑な機能だったり、何らかの理由で実装担当者と修正担当者が異なる場合にコードの歴史の積み重なりが発生しやすいです。
開発メンバーの変遷
開発チームのメンバーの入れ替わりも、コードの歴史を形作る一因です。
エンジニア一人一人にはそれぞれ異なるコーディングスタイルや設計思想があったり、技術レベルが異なるため、メンバーが変わるたびにコードにその影響が現れます。
もちろんコーディングルールを設定したり、エンジニアの採用にテストを設ける等である程度対策は可能ですが、「複数のエンジニアが全く同じコードを書けるようにする」というのは少々非現実的です。
さらに、新しく入ってきたエンジニアが既存のコードを完全に理解する前にコードに修正を加えることだってあり得ます。
ゲーム業界はそこそこ人の入れ替わりが激しいので、いろいろな人が修正してきたコードを見かけるのは珍しくありません。
「コードの書き方やコメントの付け方が画面毎にバラバラ」なんてのはよくあることです。
コードの歴史の重みが修正を難しくする理由
コードの歴史が積み重なっていくと、その重みは修正難易度に大きく影響を与えます。
最終的に数行の修正で済むような対応でも、コードの歴史のせいで信じられないくらい時間を取られることもあります。
コードが読みにくい
歴史のあるコードは長いことが多いです。
コードが長いということは読むのに時間がかかるということであり、読むのに時間がかかるということは読みにくいということになります。
ただ長いだけでコードの構成がきれいに整っていればそこまで問題にはなりませんが、大抵はスパゲッティコード化していることが多いです。
どんなにコード修正に気を遣っていても、「本当はAの処理はここに入れたいけど、Bの処理の関係であそこに入れざるを得ない」「Cのデータを取得するために、どうしてもDのメソッドを使わざるを得ない」みたいな問題に出くわしたりします。
皆さんも覚えがあるのではないでしょうか?
影響範囲が見えにくい
コードの読みにくさにも関連しますが、歴史のあるコードは影響範囲が見えにくいです。
歴史がある分、様々な処理を担うようになっている場合が多く、なかなか修正しにくいコードになっていたりします。
しっかり時間をかけて各処理の内容を理解すれば、影響範囲を特定することは可能です。
しかし、ちゃんとした設計の責務がシンプルにまとめられたコードの修正に比べると何倍もの時間が取られることは想像に難くありません。
また、いざ修正が完了してもテストで重大な問題が見つかる、なんてこともあります。
そしてその問題に対処するためにさらに修正を重ねて歴史を積み上げていってしまう、なんてこともよくあったりします。
ドキュメント不足
歴史のあるコードについてのドキュメントは不足していることが多いです。
全くドキュメントがないケースは珍しいですが、現状を正確に記載していない古いドキュメントであるケースはよくあります。
ドキュメント不足の原因はあきらかです。
コードに歴史が積み重なっているということは、修正が入る頻度が多かったということです。
そして修正が入るたびにドキュメント修正をする必要があるのですが、常にその余裕があるとは限りません。
さらに言うとドキュメントが不足していてもすぐさまシステムに問題が発生するわけでもないので、ついついドキュメント修正を後回しにしてしまったり、そもそもドキュメント修正を忘れてしまうこともあります。
そうして出来上がるのがドキュメント不足の惨状です。
コードの歴史を読み解く手がかり
歴史のあるコードの修正が難しいのは先に述べた通りですが、ひたすらコードを読み解くしか解読方法がないかというとそういう訳でもありません。
出来立てほやほやのシンプルなコードに比べると解読が難しいのは変わりませんが、手掛かりをたどっていくことで少しずつコードの歴史を読み解くことができます。
バージョン管理システム
GitやSubversionといったバージョン管理システムは、コードの歴史を読み解くための最も強力なツールです。
コミットメッセージや変更履歴を確認することで、どのタイミングでどのような変更が行われたのかをたどることができます。
また、それらの変更が反映されたプルリクエストを確認するのも非常に有効です。
エンジニアによってはコミットメッセージやプルリクエストの説明にどういう理由でどういう修正を行ったかを明確に記載してくれている場合もあります。
正にコードの歴史を読み解きたい人が欲している情報です。
仮にコミットメッセージやプルリクエストに詳細な説明が残っていなくてもまだ手はあります。
誰が変更したかはしっかり残っているので、その人に直接聞いてみましょう。
当の本人がすでに在籍していない場合は、当時のことを知っていそうな人に聞いてみるのもアリです。
チャットの履歴
プロジェクト内でSlackやChatworkといったチャットツールを利用しているのであれば、当時のやり取りの履歴をたどるのもコードの歴史を読み解くための重要な手がかりです。
まずは関連するキーワードで検索してみましょう。
バージョン管理ツールと組み合わせて、コードに変更があった時期のチャットのやり取りを調べるのも効果的です。
難しいコードの修正ほど議論が活発になりやすいので、エンジニア同士で何やら議論を積み重ねていそうなスレッドを覗いてみましょう。
チケット管理システム
JIRAやRedmineといったチケット管理システムも手掛かりの宝庫です。
コードに関連するチケットを調べることで、どのような問題に対して修正が発生したのかを知ることができます。
ただし、プロジェクトによっては過去のチケットの数が膨大になっているものもあります。
機能名やクラス名、バージョン番号といった情報でしっかり絞り込みをかけてから調査しましょう。
「コードの歴史」という存在を知ることのメリット
ここまで「コードの歴史」について解説してきました。
あってもあまり嬉しくないコードの歴史ですが、こういうものがあるということを知っておくメリットはけっこうあったりします。
クソコードに対して少し優しくなれる
「無駄な処理を何回も実行している」「余計なDBアクセスが多すぎる」等といった謎コードというよりはクソコードと呼ばれ忌み嫌われるコードが世の中にはあります。
そんなクソコードに出くわしてしまった時に、コードの歴史の存在を知っていれば「何か事情があったのかも?」と思えるようになり、すぐさま怒りの感情にとらわれてしまう機会を減らせます。
(もちろんクソコードは悪ですし、エンジニアたるものクソコードを書かないよう努力は必須です)
コード修正の見積もりの精度が上がる
常に修正対象のコードに歴史が積み重なっていないかを意識することで、見積もりの精度が上がります。
具体的には「歴史が積み重なっているコードだから事前調査の時間が必要」「かなり歴史のあるコードだから思わぬ問題が見つかり工数が膨れ上がる可能性が高い」といったようなことがわかるようになります。
長期の開発に役立つ
コードの歴史というものは開発が長期にわたるものほど発生しやすく影響も大きいものです。
つまり長期の開発において、できるだけコードの歴史を積み上げないようリファクタを欠かさないのが重要ということです。
もちろん常に良い感じにリファクタができる余裕は生まれないと思いますが、意識するとしないとでは大きく変わります。
また、どうしてもコードの歴史が積み重なって来てしまった場合でも、ドキュメントをしっかり残そうという考えもできるようになります。
この場合のドキュメントというのは言わばコードの歴史解説書です。
後々そのコードを修正することになるエンジニアにとってとても貴重な情報となるでしょう。
まとめ
コードの歴史というのはできれば積み重ねたくないものですが、なかなかそうもいかないのが現実のシステム開発だったりします。
先ほども少し述べましたが、リファクタやドキュメントの整備、重要な事柄のコメント記載の徹底等、後のコード修正が少しでも楽になる工夫をしていきましょう。
歴史あるコードを修正するのは非常に面倒で大変なことも多いですが、開発スキル向上やそのシステムへの理解を深めるのに役立つことも多々あります。
挑戦する機会があればぜひとも一度は挑戦してみてください。
※体力と気力が充実しているタイミングで挑戦してください
コメント