コーディング規約は本当に必要なのか

thumbnail

いうまでもなく、コーディング規約は重要なものです。

実装者ごとのばらつきを抑えることで可読性・予測可能性をあげることができますし、良くない書き方を禁止することで品質を底上げすることもできます。

私自身いわゆる『ルールを決めることが仕事』だった時期もあり、ひたすらコーディング規約をドキュメントにまとめていた時期もありました。

一方でここ数年はフリーランスエンジニアとして同時に2、3案件と進めている中で、コーディング規約が生産性を下げる要因にもなりうるんじゃないかと感じることが出てきました。

本記事は、そのコーディング規約への疑問を問題提起の意味を込めて考察していきます。

コーディング規約のいまむかし

まず前提として、『コーディング規約』の重要性は今と昔で変わってきている印象を受けます。

昔は、インデントが人によって空白かタブかで違うなんてことはザラで、それこそファイルの文字コードが違って重篤な不具合が発生みたいなこともありました。
コードレビューも『規約にあってるか』が多くを占めていた覚えがあります。

一方で今は静的解析ツールも進化して多くの規約が自動で確認・修正できるようになりました。

それこそ『インデントは空白何個か』なんて意識しなくても、エンター押したら勝手にAuto Fix走るような世界になりました。

静的解析さまさまですね!

逆に言えば、現代あえて明示化される規約は必然的に『静的解析できない部分』となります。

本記事で問題提起したいコーディング規約は、まさにこの『静的解析から漏れたもの』です。

フリーランスや副業との相性

さて、フリーランスエンジニアで働いていく中で何が問題だったかというと、まず『日によってルールが変わる』という点です。

プロジェクトが変わればルールも変わるわけで、「月曜日はこの書き方で...」「火曜日はこの書き方で...」となっていきます。

毎日同じ書き方をすれば手に馴染みますが、日によって変わると手に馴染むこともありません。

「...あ、今日はtypeじゃなくてinterfaceで書く日だった」「この企業はどっちだっけ...?」みたいにたびたび手が止まることとなります。

何百行と書かれた規約や、散らばったドキュメント、言語化されてないルール全てを完全に守るのは難しくもなっていきます。

もちろん時間にしたら1日数秒・数分程度かもしれません。しかしそれが存在することによるコストが少なからず存在するのは事実ではあります。

維持コスト

コーディング規約の維持は当然、時間的なコストがかかります。それは書く人もそうですし、レビューする人もそうです。

もちろん何週間かすれば自然と会社の規約を覚え、指摘する必要もなくなってくるかもしれません。

しかし今は業務委託や副業が多くなっており、正社員の入れ替わりも激しいです。したがってルールを覚えてもらうコストは何度も発生します。

仮に外部のエンジニアにコードレビューを頼んだとして、そのエンジニアが『会社の規約通りか』をチェックしてくれる保証はありません。

つまり文章ベースのルールを維持するのが非常に難しい状況になってきてると言えます。

ルールの形骸化リスク

規約を作る以上、それが全体で守られてる状態を維持するべきです。

守られてない状態が続くとそれは形骸化していき、なんとなく「守る必要ないよね」「なんか書いてあるけど誰も守ってないよね」という空気感が形成されます。

すると本当に大事な規約も「守らなくて良い」となってしまう恐れがあります。

また人が意識できるものには限界があるため、ルールがたくさんできてもそれ全てを守ってもらうことは現実的に無理があります。

つまり大事なルールを守ってもらうためにも、不必要なルールを作らないのが重要です。

そうなったときに、たとえば「typeとinterfaceどちらを使うか」は果たして他のルールより優先すべき事柄なのか疑問を感じます。

リリースの遅れ

IT業界において、機能をいかに素早くリリースするかは非常に重要なものです。

特にベンチャーだと、それが会社の成否を分けることもあります。

業務委託で週数日の勤務だと、コードレビューのキャッチボールだけで何週間もかかってしまうことがあります。

実際に「コーディング規約とのずれ」を解消するために、リリースが何週間も遅れてしまうことも経験上ありました。

もちろん自分もエンジニアとして、書き方が揃ってないと気持ち悪いと感じることは何度もあります。

しかしその不快感の解消は、リリースを数週間遅らせるコストに対する見返りとして本当に釣り合っているものなのでしょうか。

「書き方を揃えろ」の暴力性

「他がこう書いてあるから揃えろ」はそれこそどんな状況下でも使える言葉です。

たとえば「書き方が揃ってない!」と以下のようなレビューがされたという投稿をSNSで見たことがあります。

const hasCompany = !!context?.user?.company

他がifで、Optional Chainingを使わず存在確認をしているため、次のように修正しろとのことです。

let hasCompany: boolean;

if (context && context.user && context.user.company) {
    hasCompany = true;
} else {
    hasCompany = false;
}

この修正の必要性は、疑う人も多いのではないでしょうか。

もし本当にその書き方の方が優れているのであれば、その理由を説明すれば相手も納得した上で修正してくれるはずです。

一方で「書き方を揃える」が修正理由ということは、合理的な理由が説明できないことの裏返しでもあります。

「揃ってないと気持ち悪い」

もちろんこの事例は極端かもしれませんが、『書き方を揃える』は大なり小なり『自分の見慣れた書き方に揃えたい』という欲求ドリブンであるように感じます。

人によって揃えたいと感じる点は異なるため、チームメンバーがこうした欲求を感じるたびにルール化していくと、無限にルールは増えていくことになります。

そうした暴走に歯止めを効かせるためにも、『コーディング規約が増えることによるコスト』への意識は重要だと感じます。

何を揃えるか

もちろん、だから規約をなくそうというわけではありません。

無駄な規約にコストをかけない一方で、大事な重要なルールにはフォーカスするべきです。

命名規則

コーディングにおいて命名は非常に重要なものです。

たとえばisLoadingの中身はbooleanな前提で読み進めるでしょう。PREFECTURESは定数で配列な前提で読むでしょう。

同じ概念に対する命名がバラバラで、バックエンドはorganizationと読んでるものがフロントエンドだとcompanyと書かれてるなんてこともあります。

こうした前提は、崩れるとコードリーディングに時間がかかりますし、認識違いからバグを生むリスクもあります。

TypeScriptだと@typescript-eslint/naming-conventionなどのルールもありますが、こうしたルールはたとえ人力になったとしても全力で維持すべきものだと感じます。

コードの実装方法

たとえばJavaScriptで文字列を数値変換する際に、Number(str)+strparseInt(str)があります。

NaNの扱いなどからNumber(str)が良いみたいな意見はありますが、一方でこうした実装方法はあえてルール化して統一する必要もないかと考えています。

もちろんそのコードにおいて明確に理由がある場合は指摘されて然るべきですし、相手が知らないだけならそれを教えてあげるのは大事です。

しかしそれをルールにすると無限のパターンが出てきますし、「parseIntが適切な場面でも思考停止でNumberにする」などむしろ足を引っ張る場面も出てきてしまいます。

強制的に最低限の品質を担保する目的で大企業がルール化するなら理解できますが、コミュニケーションで解決できる人数規模であれば勉強会などで共有するほうが健全かと思います。

自動化できるルール

今は多くのルールがlinterで提供されています。

意外とコードレビューで指摘している大部分がlinterで担保できる範囲だったみたいなケースもあります。

また「この関数はreplace予定なので使わないでください!」なんてコメントも@deprecatedをつければすむ話だったりもします。

ルールを増やす前に、まずは『このルールを自動化できないか』を調べると意外と見つかるものです。

そうすればルールをGitで管理することもできますし、ルールが守られてることをCIで確実に担保することができます。

ルールは守られない

そもそも、自分の経験上何かをチーム全体に強要するのは相当ハードルが高いことだとひしひし感じています。

自分自身、正社員の頃は必死にまとめたドキュメントが読まれないことに苛立ったこともありました。

しかしいろいろ経験した今だと、ドキュメントは存在に気づかれず、メンションしてもほとんど読まれず、読まれても忘れられ、メンテされないまま、古い情報となって実態と乖離するものだと感じます。

そうなるとドキュメントはさらに信用を落とし、「ドキュメントにはこう書いてあるけど、実際のことは誰かに聞いてみないと分からない」となっていき、さらに読まれなくなっていきます。

数人のチームであれば自分が全てコードレビューして強要することはできるかもしれませんし、ルールからはみ出たものを勝手に治して回ることはできるかもしれません。

ただ特に週1〜3の業務委託だと、個人の影響力で自分の理想を実現するのに限界があります。

結局なところドキュメントを何百行もまとめるより、lintのルールを1行足した方がはるかに意味のある行動ではないでしょうか。

おわりに

コーディング規約への問題提起として、考察をまとめていきました。

全体として否定的に書きましたが、あくまで今までの常識に対するアンチテーゼとして一方的な論調で記載しました。なので実際には、チームとして何を重要視するかによって変わっていきます。

たとえばリソースをかけてでも品質を担保したい大企業と、スピード重視のベンチャーでもまた意思決定の基準は変わっていきます。

この記事がコーディング規約がどのようなときに必要で、どのようなときに必要ないかの判断の一助になれば幸いです。


@dorarep
小学生の頃からフリーゲーム作ってました。今はフリーランスでフルスタックエンジニアしてます。