渡る世の中クソコードだらけ。
そんな中、
こんなクソコードは書くな
とか、
コードってのはこう書くんだ
とか、
そもそも〇〇指向ってのは(ry
とか、そういう記事はたくさんあります。
じゃあ、今あるクソコードはどうすればいいんだ? ――とある新卒エンジニア
世の中にはクソコード、あるいはクソコードの原因となるパターンを集めたアンチパターンというものがありますが、これはあまりにも多く、離散的で、抽象的です。
何故か。クソコードというものが、あまりにもバリエーション豊富だからです。
この記事はそういった蓄積済みの知識に頼らず、今目の前にあるクソコードをどのように読み解き、如何に理解し、どのように処理すべきかを考える手がかりとなることを願って記述されています。
何も学ばず今ある武器だけで戦う時、最も重要なのは、今目の前にあるクソコードには、どういうクソがひっついているのか分類することです。
問題点を分類して記録することに成功した場合、あなただけでなく、今、あるいは今後そのコードや周辺コードを保守する面々の助けになります。
1. 作成者
世の中でよく言われる言葉の一つにこういうものがあります。
罪を憎んで人を憎まず。転じて、我々の業界ではコードを憎んで人を憎まずともよく言われます。読んで字のごとく、悪いのは罪/クソコードであり書いたやつではない、という、非常に人道的な教えですね!
敢えて言います。憎んでください。
……と、ここまで書くと非常にキャッチーです。
怒られそうなので念の為言っておきますが、「憎め」というのは、流石に比喩です。一応個人を憎むのは辞めておいたほうがいいでしょう。病みます。
「(クソコードの)作成者」というひとつのタグとして、「誰が書いたのか」覚えておけ、という意味です。
クソコードが発生する要因の一つに、作成者の能力不足が挙げられます。
クソコードの作成者が絶対に能力不足であるとは言えませんが、能力不足な人間が作成したコードは高確率でクソです。
そして、能力不足に起因するクソコードは、作成者ごとに癖があります。
あくまで私の経験上の話ですが、これは「出来るやつ」の癖よりも強烈で、臭います。
作成者ごとに「こいつはこういうことをやらかすんだな」と分類しておくのは、コード中の危ないところをあぶり出す上で重要です。
特にオフショアに流されたコード、あるいは当時の開発者が残っていないような古いコードを読む場合、この手法は意外と我々を救ってくれます。
え? 作成者の情報が残ってない? ……まあ、そういうこともあるよね……
2. コピペ
「同じような処理があった時、それらはまとめられるべきか?」
実は下手にまとめないことがよいことも珍しくありません。
しかし現実には、まとめるべきコードをまとめずに各所にバラバラと好き勝手書いていることのほうがよっぽど多いです。
もっというと、好き勝手書いているだけならまだマシな方で、大抵はなんとコピペです。
その処理が何をやっているかなんて何も考えずコピペしていることなんて珍しくもなんともありません。
というわけで、コピペ部分は逐次分類しておくと役に立ちます。
よく水平展開なる単語で「同じような部分が他にもあるからまとめて直せ」という指示がなされます。
これ、割と高確率でコピペで作られた部分いっぱいあるから探して直せという意味だったりします。予め気づいた時にまとめておくと、あとで楽ができます。
3. 名前
クラス。メソッド。メンバ変数。ローカル変数。名前をつける機会はいっぱいあります。
もしも名前が駄目なせいで読めない場合、対応表を作りましょう。
そしてせめて名前の修正だけでもできないか探りましょう。
今日日、IDEの機能を使えば名前の変更ぐらいはサクッとやれます。
もしも名前の変更すら拒否されたら、その現場は異常だと認識すべきです。そして、その異常から身を守るために対応表を手元に持ち、可能な限り更新していきましょう。
よくあるのは以下でしょうか。
##「名前は連番でつける」 - クソルールがあるパターン
SIerや古い内製系の部署にありがちです。大抵は設計から死んでいて、どうしようもありません。
こういう場合、対応表を作ろうが何をしようが何の意味もありません。もともと対応表前提なので。
むしろ、2. のコピペ部分抽出に力を入れるべきでしょう。なにせ、こういう場合はほぼ全文がコピペでできています。
分類してみたら1万行がたった10種類の繰り返しだった、なんてことも……
なお、稀に特にそういうルールはないけどなんとなくとかツールがそういう風に生成するからとか、割としょうもない理由で発生していることもあります。SQL でテーブルいっぱい書くから t1, t2, t3... とかやってる、みたいなパターンに多いですね。
こういう場合はむしろ対応表作成必須です。ガンガン作って、理解するために使いましょう。
「実績があるから変更できない」 - コードの変化を嫌がるパターン
割とめんどくさい、社内政治的な事情が絡むパターンです。「バグが出ると評価が下がる」とか、そういう前時代的な評価をやっている現場で起こります(ろくにバグ管理がなされていないことも多いです)。
政治的な事情が絡むので、対応は困難です。
上役に「なんとかしろ」と言えば通る(誰も言い出さなかっただけな)事もあれば、上役の上役(場合によっては部長~社長レベルのような "雲の上" から)「動いてるものに手を入れるような無駄な真似をするな」なんて馬鹿げた命令が下っていることもあります。
よっぽどあなたに根性があるか、上役が話の分かる人間でないなら、諦めたほうがよいでしょう。困ったことに。
「英語も日本語もプログラミングもわからない人間がコード書いた」 - 悪いオフショア/ロースキルな作成者のパターン
対応できるだけに、却ってタチの悪いパターンです。
例えば*「setA」と書いてあるのに引数も取らず、どこかをガチャガチャ書き換えながらついでにAも書き換える、ようなメソッドがあったら*?
例えばある英単語がスペルミスで別単語に化けてしまっていたら?
……バカげた話のようですが、ままあるのです。困る。ほんとに困る。
スペルミス、単語の選択ミス、名称の取り違え、仕様の解釈ミス、知識や前提情報の不備などなど、考慮すべき内容が無限に膨れ上がります。名前がおかしいだけなのに、です。
何故か? 名前が信頼できないということは、関数などの塊を「そういう動作をするんだろうな」と信頼できないということを意味するからです。
こういう場合、一気に対応表をつくるというよりは、少しずつ、見つけ次第に、変な名前と本来意味していたであろう内容の "対訳表" を、書き足していく形で作っていくべきでしょう。
1.の作成者分類と合わせれば、最終的にどのようなパターンが多いのか見えてくるはずです。
このパターンは時に語学、あるいはそこまで行かずとも雑学的な知識が役に立つこともあります ― 例えば、「event」は中国語で「事件」だ、とか。
おわりに
とりあえず、現状で私がよく使う3パターンを挙げました。
実際問題として、仕事でクソコードと出くわすことを避けるのは、自分がありとあらゆる全てのコードを書くのだとしても不可能でしょう。
三日前の自分は他人、という言葉もあります。半年前に間に合わせで書いた自分のコードがあとから見たら読みようのないクソコードだったなんて珍しくもありません。
(そういうコードに限って "動いてるから" という理由でプロダクション・コードとして採用されてたりします。畜生め!)
この記事が少しでも「読み」の取っ掛かりたらんことを。
なお、今回の記事は「今読む時にどうするか」を主題としたので記載しませんでしたが、やっぱりいちばん重要なのは、そもそも世の中どんなクソコードがあるのか知っておくことです。だいぶ違います。
アンチパターンの本を読むのもいいですが、もっと手っ取り早く、ウンコード・マニアあたりでクソコードの実例を読んでみるといいでしょう。
人の振り見て我が振り直せ。クソコードを学べば、自分もよりよいコードを書ける……かも。