2.1

View in English

2.1 コーディング標準とスタイル

概要と動機

コーディング標準とは、多くの人が、一人の注意深い作者が書いたかのようにコードを書けるようにする、共有された規約です。命名、書式、ファイルの配置、イディオム、エラー処理、そしてチームが好むパラダイムを含みます。小さなチームでは、個人の好みが通用します。大きなチーム(何百、何千のエンジニア、多くの契約者、高い離職)では、一貫性のなさが、あらゆる読み、あらゆるレビュー、あらゆるオンボーディングで支払う税になります。標準は、数えきれない小さなスタイルの論争を、機械が代わりに徹底する一度きりの決定に変えます。

大きな組織にとって、賭け金は具体的です。コードは書かれるよりはるかに多く読まれます。企業や政府の設定では、一行のコードが、作者が去って何年も後に、監査人、セキュリティレビュアー、保守担当者によって読まれることがあります。一貫したスタイルは、その読む精神的コストを下げ、バグの表面積を縮め、リンター(バグの可能性やスタイル違反を自動的に指摘するツール)、セキュリティスキャナー、リファクタリングツールにわたって、自動解析を信頼できるものにします。金融サービス、ヘルスケア、防衛、公共部門のシステムのように規制が適用される所では、標準は、コードベースが保守可能で管理されているという証拠の一部にもなります。

現代的なアプローチは、スタイルを、継続的な人間の判断の問題ではなく、解決済みで自動化された関心事として扱うことです。フォーマッターとリンターは、エディタ、コミット前フック、そして継続的インテグレーション(CI)、つまりすべての変更に対して実行される自動のビルドとテストのプロセスで動きます。機械がスタイルを徹底するので、レビューの注意を設計と正しさに使えます。目標は、それ自体としての均一性ではありません。摩擦の除去です。基本を学び直さずに、サービスやチームの間を移動できるべきです。

主要原則

  • 一貫性は個人の好みに勝ります。あらゆる所に適用される合意された単一のスタイルは、不均一に適用される「最良の」スタイルよりも価値があります。
  • 徹底を自動化します。フォーマッターとリンターが信頼できる唯一の情報源であり、空白についてのコードレビューのコメントではありません。
  • 元の作者ではなく、読み手と保守担当者のために最適化します。
  • 独自のハウスルールより、より広い言語コミュニティがすでに使っている規約を好みます。
  • 標準を採用しやすくします。誰も読まないPDFではなく、共有の設定、テンプレート、ツールを提供します。
  • スタイルのルールは、少なく、擁護でき、曖昧さがないものにします。どのルールにも徹底の仕組みがあるか、さもなければ単なる提案です。
  • 命名は、可読性に対する最もてこの効く決定であり、明示的なガイダンスに値します。

推奨事項

言語ごとに標準のスタイルガイドを採用する

使用する言語ごとに、広く認められたスタイルガイドをベースラインとして採用し(たとえば、その言語のコミュニティやベンダーのガイド)、組織が必要とする差分だけを文書化します。ゼロからハウススタイルを発明してはいけません。選択を中央の見つけやすい場所に公開し、コードのようにバージョン管理します。

フォーマッターを交渉の余地のない既定にする

フォーマッターのある言語には、意見の強い自動フォーマッターを使い、リポジトリにチェックインされた単一の共有設定を用います。保存時に自動的に適用され、CIで検証されるので、書式がレビューで話題になってはいけません。強いフォーマッターのない言語では、リンターの設定を一つ選び、同じように扱います。

リンターを助言ではなく、徹底されるゲートとして動かす

リンターを合意されたルールセットで設定し、違反でビルドを失敗させ、ルールセットをバージョン管理に置いて、変更がレビューを通るようにします。自動修正できるルール(自動的に適用する)と、人間の判断を要するルール(指摘してブロックする)を分けます。新しいルールは「warn」モードで導入し、バックログを片付けてから、「error」に昇格させます。

複数の層で徹底する

即座のフィードバックのためのエディタ統合、ローカルでの徹底のためのコミット前フック、権威あるゲートとしてのCIチェックを提供します。違反を早く捉えるほど安くつきます。ローカルのフックは回避されうるので、CIが最後の砦でなければなりません。

命名に明示的なルールを与える

言語ごとにケース(大文字小文字)の規約を標準化し、意図を表す名前を求め、誤解を招く略語を禁じ、真偽値、コレクション、単位、非同期操作の規約を定義します。同じ概念があらゆる所で同じ名前を持つよう、ドメインの語彙を共有の用語集に書き留めます。

多言語の一貫性を意図して管理する

複数の言語にまたがるコードベースでは、構文が異なっても、一貫した概念(エラー処理のパターン、ログの構造、プロジェクトの配置)を目指します。言語ごとの設定を中央のリポジトリから提供し、新しいサービスがテンプレートやスキャフォールディングを通じて自動的に標準を引き継ぐようにします。

イディオムとパラダイムを成文化する

書式を超えてください。エラーの扱い方、モジュールの構造化の仕方、例外と結果型のどちらをいつ使うかなど、好むイディオムと、チームが好むパラダイムを書き留めます。本当の可読性と保守性が宿るのはここです。

トレードオフ: 長所と短所

アプローチ長所短所
設定ゼロの厳格な自動フォーマッター書式の議論をすべて終わらせる。即座の一貫性。オンボーディングが容易気に入らない選択の一部は交渉不可。最初に適用するときの大きな差分
ハウスルールを持つ設定可能なリンター組織のニーズに合わせられる。本物のバグ防止ルールを組み込める設定のずれ。ルールの些末な議論。保守の負担
コミュニティ標準の丸ごと採用新規採用者に馴染みがある。強いツールのエコシステム。保守が低コスト特殊な組織の制約に合わないことがある。ときどき不自然なルール
独自の社内標準組織にぴったり合う書いて保守するのが高価。採用者に馴染みがない。ツールが弱い
チームごとの自律現場の士気が高い。文脈に特化分断。チーム間の移動が苦痛。ツールの不統一

徹底される既定は、わずかな個人の自律を、大きな集団的利益と引き換えにします。レビューの摩擦の減少、より速いオンボーディング、信頼できる自動化です。主なリスクは、標準を数百のルールにまで作り込みすぎ、本物の欠陥を防ぐことなく全員を遅くすることです。ルールセットを小さく、証拠に基づいて保ち、保守が安く済むよう、既存の標準を採用する方向に傾けてください。

チームで議論すべき問い

  1. どのリンタールールがビルドを失敗させるべきで、全員を止めずにルールを警告からエラーへ昇格させるにはどうしますか。 本章は、どのルールにも徹底の仕組みが必要で、新しいルールはwarnモードで導入し、バックログを片付けてから、errorに切り替えるべきだと論じています。大きなチームでは、汚れたコードベースに対してルールをerrorに切り替えると、一夜にして何百もの無関係な変更をブロックします。会議に確かな証拠を持ち込んでください。各候補ルールの現在の違反数、そしてそれが自動修正可能か、人間の判断を要するか。企業や政府の設定では、合否の線は監査ゲートにも反映されるので、曖昧なルールセットはコンプライアンスの説明を弱めます。段階的な展開を決めてください。できるものは自動修正し、片付けを予算化し、それからゲートにします。

  2. レガシーコードに初めてフォーマッターを適用するとき、その再整形がgit blameを台無しにし、レビューを溺れさせないようにするにはどうしますか。 トレードオフの表は大きな最初の差分を警告し、アンチパターンの節は、再整形のコミットをロジックの変更と混ぜることを指摘しています。一回の広範な再整形は、数千行を書き換え、blameが本当の作者ではなく再整形を指すようにして、何年も後にデバッグする誰にとっても害になります。再整形は、一つの隔離された、明確にラベル付けされたコミットとして行い、blame無視ファイルに登録して履歴が役立つままにします。誰が何を変更したかをたどる監査人にとって、その隔離は、きれいな証拠と雑音の違いです。コードに触れる後ではなく、前に順序を合意してください。

  3. 命名の用語集とドメインの語彙は誰が所有し、新しい用語はどう追加されますか。 本章は命名を可読性に対する最もてこの効く決定と呼び、ドメインの語彙を共有の用語集に書くよう求めています。名前を持つ担当者がいなければ、同じ概念がチーム間で三つの異なる名前を拾い、静的解析と検索ツールの信頼性が失われます。具体的なシグナルとして、すでにコードベースで名前が衝突している概念の例を持ち込んでください。担当者を一人と、軽い提案の経路を割り当て、用語の追加や改名が、あらゆるプルリクエストでの議論ではなく、小さくレビューされる変更になるようにします。答えはオンボーディングを変えます。新規採用者は、一貫しないコードから意図を逆解析する代わりに、一つの用語集を読みます。

  4. 言語ごとに、認められたコミュニティやベンダーのスタイルガイドを丸ごと採用していますか。そして、ハウスの差分が実際に正当化されるのはどこですか。 本章は、既存の標準をベースラインとして採用し、組織が必要とする差分だけを文書化すべきだと論じています。独自の標準は書くのが高価で、採用者に馴染みがないからです。相反する引力は本物です。内部の制約(セキュリティルール、レガシーフレームワーク、アクセシビリティの義務)が、ときにコミュニティの既定と本当に衝突し、保持するすべての差分は、今後ずっと自分が所有して保守するルールになります。提案する差分のリストを、それぞれの動機となる具体的な制約とともに会議に持ち込み、単なる好みの差分はどれでも切る準備をしてください。企業や政府の設定では、より広い言語コミュニティに合うベースラインは、契約者や新しいベンダーがすでに慣れた状態で到着することも意味し、オンボーディングを短縮し、監査人が求める保守性の証拠を強めます。

  5. 多言語のコードベースで、どの規約が本当に普遍的で、どれが言語固有のままで、リポジトリごとの設定のずれをどう防ぎますか。 本章は、構文が異なっても、言語をまたぐ一貫した概念(エラー処理、ログの構造、プロジェクトの配置)と、新しいサービスが標準を自動的に引き継げるよう中央のリポジトリから提供される言語ごとの設定を求めています。緊張は、ある言語のイディオムを別の言語に強いると、ぎこちなく非イディオム的なコードを生み、すべてのチームに独自の設定をフォークさせると、「標準」が何の意味も持たなくなることです。具体的なシグナルとして、現在のリポジトリごとのリンターとフォーマッターの設定の一覧と、それらがすでにどれだけずれたかを示す差分を持ち込んでください。数十のサービスを運用する大きな組織では、ルールの変更が、すべてのリポジトリに手作業でコピーされるのではなく、一度で伝わるよう、配布の仕組み(テンプレート、スキャフォールディング、共有の設定パッケージ)を決めてください。

  6. ルールを無効にするのはいつ正当で、その抑制を誰がレビューし、包括的な無効化が標準を空洞化させないようにするにはどうしますか。 アンチパターンの節は、広範なインラインの抑制を、ルールが間違っているか、チームが諦めた兆候として指摘していますが、例外を一切認めない硬直した方針は、リンターを満足させるためだけに人々により悪いコードを書かせます。軽い経路に合意してください。抑制は理由を伴い、できる限り狭いスコープに置かれ、グローバルな無視ファイルに埋もれるのではなく、レビューで見えるようにします。ルールごと、リポジトリごとの現在の抑制数を持ち込んでください。数百回抑制されたルールは、コードではなくルールについて何かを語っているからです。規制された仕事や公共部門の仕事では、説明のない包括的な抑制は、監査の説明を直接弱めます。パイプラインが、マージされたコードが合意されたゲートを本当に通過したことをもう示せなくなるからです。

セクター別の視点

スタートアップ。 速度が勝つので、一つの言語について、初日にコミュニティのフォーマッターとリンターの既定を採用し、二人目のエンジニアが来る前にコミット前フックとCIに組み込んでください。維持する時間のないハウススタイルは書かないでください。リポジトリに同梱された設定が、標準のすべてです。二つ目の言語を加えるときは、規約をゼロから発明するのではなく、その言語の標準的なガイドに手を伸ばします。

小規模事業者。 専任のツールの専門家はおらず予算も厳しいので、言語に同梱される、または並んで提供される無料の意見の強いフォーマッターに全面的に頼り、調整するのではなくその既定を受け入れてください。これは明確に、作るより買うの事例です。独自のルールセットの保守は、持っていない時間を要する一方、既製のフォーマッターはコストがかからず、スタイルの議論をすぐに終わらせます。設定をリポジトリに置き、来年雇う一人の契約者が、会話なしにそれを引き継げるようにします。

大企業。 規模が大きくなると、仕事は多数のチームにわたるガバナンスです。言語ごとの共有のフォーマッターとリンターの設定を保持する中央のエンジニアリング標準リポジトリ、それらの設定を取り込むテンプレートから生成される新しいサービス、そして準拠しないマージをブロックするCIゲート。ルールセットをコードのようにバージョン管理し、変更を定期的なレビューに通して、標準が漂流するのではなく意図して進化するようにします。見返りは、エンジニアが馴染みのあるコードへチーム間を移動でき、すべてのリポジトリが一貫しているために、自動化されたツールが信頼できるシグナルを生むことです。

政府。 調達と説明責任が選択を形づくります。運用認可(ATO)の要件の一部として、特定のスタイルとセキュリティのルールセットを義務づけ、マージされたすべての変更が合意されたゲートを通過したことを示すレポートを、監査の証拠としてパイプラインに出力させます。フォーマッターは自動的に適用されるので、複数のベンダーや契約者のコードが一貫して見え、契約が終わったずっと後も公共の保守の仕事を守ります。独自のルールより、認められたコミュニティのベースラインを好み、標準を透明にして、将来のどの供給者も、独自のロックインなしに採用できるようにします。

事例

スタートアップ。 4人のスタートアップは、一つの言語について、初日にコミュニティのフォーマッターとリンターの既定を採用し、コミット前フックとCIに組み込んで、誰もレビューで空白について議論しないようにします。設定がリポジトリの中に同梱されているので、5人目と6人目の採用者はそれを自動的に引き継ぎ、書式のコメントを一度も目にしません。後でチームが二つ目の言語を加えるとき、維持する時間のないハウススタイルを発明するのではなく、その言語の標準的なガイドを手に取ります。

大企業。 大手銀行は、数十のチームにわたって、Java、Python、TypeScriptでサービスを運用しています。言語ごとの共有のフォーマッターとリンターの設定を保持する、中央の「エンジニアリング標準」リポジトリを公開します。新しいサービスは、それらの設定を取り込むテンプレートから生成されるので、すべてのリポジトリが準拠した状態で始まります。CIはあらゆる違反でマージをブロックし、四半期ごとのレビューがルールの変更を統治します。すべてのリポジトリが馴染みのあるものに見えるので、チーム間を移るエンジニアのオンボーディング時間は目に見えて減ります。

政府。 レガシーシステムをモダナイズする公的機関が、運用認可(ATO)、つまりシステムを本番で動かすために必要な正式な承認の要件の一部として、アクセシビリティとセキュリティのリンティングのルールセットを義務づけます。スタイルへの準拠は監査の証拠の一部になります。パイプラインは、マージされたすべてのコードが合意された静的解析のゲートを通過したことを示すレポートを生成します。フォーマッターは自動的に適用されるので、複数のベンダーの契約者が視覚的に一貫したコードを生み出し、契約が終わったあとの政府の長期的な保守の仕事を楽にします。

ビジネスケース: 動機、ROI、TCO

標準を採用するコストは、おもに一度きりです。ガイドの選択、ツールの設定、そして一回の大きな最初の再整形コミットの適用。徹底が自動化されているので、継続的なコストは低いものです。標準を採用しないコストは、繰り返し発生し複利で増えます。すべてのレビューがスタイルに数分を費やし、すべてのオンボーディングが遅くなり、静的解析ツールは雑音を生み、一貫しないコードはバグを隠します。大きな組織全体では、それらの数分が積み上がって、フルタイム換算の損失になります。

見返りは、レビューの遅延の短縮、スタイルに関するレビューコメントの減少、より速いオンボーディング、自動化されたツールからのより高いシグナルとして現れます。規制された環境では、監査への備えというさらなる見返りがあります。実証可能で徹底された統制は、コンプライアンスレビューの労力とリスクを減らします。リーダーシップに論拠を示すには、標準を、開発者の生産性と監査の姿勢に対する、低コストで高いてこの効く手段として枠づけ、レビューコメントの分析とオンボーディングのサーベイデータを使って、一貫性のなさの現在のコストに数字を付けてください。

アンチパターンと落とし穴

  • コードレビューで議論されるスタイル: 徹底が自動化されていない兆候。ルールをツールに移します。
  • 読まれない標準の文書: 徹底のないウィキのページは飾りです。どのルールにも仕組みが必要です。
  • ルールの乱立: 本物の欠陥を防ぐことなく仕事を遅くする、何百もの些末なルール。
  • 設定のずれ: 各リポジトリが独自のリンター設定をフォークし、「標準」が何の意味も持たなくなること。
  • 機能開発の最中にリポジトリ全体を整形する: 再整形のコミットをロジックの変更と混ぜると、レビューとblameが壊れます。大きな再整形は、隔離された明確にラベル付けされたコミットで行います。
  • 包括的な抑制でリンターを無視する: 広範なインラインの無効化は、間違ったルールか、諦めたチームを示します。
  • 所有者のいない標準: 明確な所有者がいなければ、ルールは進化せず腐ります。

成熟度モデル

  • レベル1、開始: スタイルは作者ごとで反応的です。共有の設定はなく、書式はレビューで議論され、その日最も気にかけた人によって決着します。
  • レベル2、発展: 個々のチームがフォーマッターとリンターを採用しますが、設定とルールセットはチームごと、リポジトリごとに異なり、一貫性は各チームの境界で止まります。
  • レベル3、標準化: 言語ごとの中央の共有設定が文書化され、組織全体で徹底されています。CIは準拠しないマージをブロックし、新しいリポジトリはテンプレートやスキャフォールディングを通じて標準を自動的に引き継ぎます。
  • レベル4、管理: 標準はデータで測定され、制御されます。違反率、抑制数、スタイルに関するレビューコメント、オンボーディング時間がベースラインに対して追跡され、ルールの変更は、意見ではなくその証拠に基づいて昇格または廃止されます。
  • レベル5、オーケストレーション: 標準は継続的に改善され、組織全体に統合されています。多言語のイディオムとドメインの語彙は文書化され徹底され、徹底はほぼ摩擦がなく、ルールセットは言語、ツール、組織のニーズが移るにつれて適応します。

議論のためのアイデア

  • 徹底されるルールと、エンジニアの判断を信頼する文書化されたガイドラインの境界線はどこにありますか。
  • 愛されているコミュニティのルールが、本物の内部の制約と衝突するとき、組織はどう扱うべきですか。
  • 標準は誰が所有し、ルールの変更は混乱なく、どう提案され、議論され、展開されますか。
  • 多言語のコードベースで、どの規約が本当に普遍的で、どれが言語固有のままであるべきですか。
  • 大きなレガシーのコードベースに、混乱を招く一括の再整形なしに、標準を後付けするにはどうしますか。
  • 機械的なフォーマットを超えて、イディオムを提案したり徹底したりするうえで、AI支援のツールはどんな役割を果たすべきですか。

要点

  • スタイルを自動化された解決済みの問題として扱い、人間が設計と正しさをレビューできるようにします。
  • 既存のコミュニティの標準を採用し、差分だけを文書化します。
  • エディタ、コミット前、CIの層で徹底し、CIを権威あるゲートとします。
  • ルールセットを小さく、擁護でき、中央で統治されたものに保ちます。
  • 可読性が本当に勝ち取られるのは、空白ではなく、命名とイディオムです。

参考文献とさらなる読み物

  • Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
  • Andrew Hunt and David Thomas, The Pragmatic Programmer
  • Steve McConnell, Code Complete
  • Dustin Boswell and Trevor Foucher, The Art of Readable Code
  • Kevlin Henney (ed.), 97 Things Every Programmer Should Know
  • Google, Google Engineering Practices and language style guides (as reference exemplars)