アプリケーションアーキテクチャ

命名とコード規約 ― 議論を自動化で終わらせる ― 生成AI時代のアーキテクチャ超入門

命名とコード規約 ― 議論を自動化で終わらせる ― 生成AI時代のアーキテクチャ超入門

本記事について

当サイトを閲覧いただきありがとうございます。 本記事はシリーズ『生成AI時代のアーキテクチャ超入門』の「アプリケーションアーキテクチャ」カテゴリ第3弾として、命名とコード規約について解説する記事です。

コードを書く時間より「読む時間」のほうが圧倒的に長い。読みやすさはチーム生産性そのものです。本記事では命名の基本原則・ケースの使い分け・Linter/Formatter・ディレクトリ構成・PRレビュー・CODEOWNERS・Gitコミット規約まで、「議論を自動化で終わらせる」規約運用の全体像を示します。

このカテゴリの他の記事

「名前」で9割決まる

命名やスタイルの一貫性は地味で、派手な成果にはなりません。ですが長期で見れば最もROI(Return On Investment、投資対効果)が高い投資の一つで、規約がないチームでは、レビューのたびに「変数名」「インデント」「括弧の位置」といった本質的でない議論が繰り返されます。こうした消耗を機械的に潰してしまえば、人間の頭は設計の議論に向けられます。

過去に、毎回のPRで「変数名はcamelCaseかsnake_caseか」の議論が湧き、1PRにつき30分以上のコメントラリーをしている現場を見たことがあります。チームにPrettierを導入した翌週には、その手の議論は消えた、という話もよく聞きます。規約はそれだけで生産性の底上げになります

優秀な設計でも、命名と一貫性が崩れていれば読めません。「人間向けの設計」を忘れないことが大事です。

命名の基本原則

良い命名には共通する原則があります。Robert C. Martin『Clean Code』で整理されたもので、「意図が明確・嘘をつかない・発音できる・検索できる」の4点を押さえるだけで、可読性は一気に変わります。

flowchart TB
    NAME([命名のチェック])
    INTENT[意図を表す<br/>d → daysUntilExpiration]
    NOLIE[嘘をつかない<br/>List<T>の中身がSet<T>はNG]
    NOAMBI[誤解を避ける<br/>process()は曖昧]
    SAY[発音できる<br/>genymdhms → generationTimestamp]
    SEARCH[検索できる<br/>1文字変数は局所のみ]
    GOOD([可読性UP<br/>コメントほぼ不要])
    NAME --> INTENT --> GOOD
    NAME --> NOLIE --> GOOD
    NAME --> NOAMBI --> GOOD
    NAME --> SAY --> GOOD
    NAME --> SEARCH --> GOOD
    classDef root fill:#fef3c7,stroke:#d97706;
    classDef rule fill:#dbeafe,stroke:#2563eb;
    classDef goal fill:#dcfce7,stroke:#16a34a;
    class NAME root;
    class INTENT,NOLIE,NOAMBI,SAY,SEARCH rule;
    class GOOD goal;
原則内容
意図を表すd ではなく daysUntilExpiration
嘘をつかないList<T> という名前で実態が Set<T> ではダメ
誤解を避けるprocess() のような曖昧な名前は避ける
発音可能genymdhms より generationTimestamp
検索可能1文字変数はループ変数程度に限定

命名はコードに書かれた最大のドキュメントです。命名が良ければコメントはほぼ不要になります。

命名規則(ケースの使い分け)

変数・関数・クラス・ファイル名をどのケースで書くかは、言語ごとに事実上の標準が決まっています。JavaScriptで変数を user_name と書いたり、Pythonのクラスを user_profile と書いたりすると、文法上は動いても読み手に違和感と認知負荷を与えます。言語の慣習はコミュニティ合意の蓄積であり、これを尊重することが読みやすさに直結します。

ケースの統一が効くのは、一貫性があると「これは何か」形から瞬時に判断できるようになるからです。PascalCase なら型、camelCase なら変数や関数、SCREAMING_SNAKE_CASE なら定数、と一目で判別できるため、読む速度そのものが上がります。

ケース用途例
camelCaseJS/TS/Java/Kotlin の変数・関数
PascalCaseクラス・型
snake_casePython / Ruby / DB列名
kebab-caseファイル名・URL
SCREAMING_SNAKE_CASE定数

言語の慣例に合わせます。同一言語内での混在は絶対に避けるのが鉄則です。

対象別の命名パターン

変数・関数・クラスなど、対象ごとに鉄板の命名パターンがあります。これに従うだけで、読む人が「これは何か」を瞬時に判断できるようになります。

対象パターン
関数動詞 + 目的語createUser, validateEmail
booleanis / has / can プレフィックスisActive, hasPermission
クラス名詞OrderService, UserRepository
インターフェース名詞UserRepository or IUserRepository(好み)
イベント過去形UserRegistered, OrderPlaced
定数全大文字・意図を表すMAX_RETRY_COUNT

イベントは過去形が鉄則です。Register ではなく UserRegistered と書くと「起きたこと」が明確になります。

避けたい命名

以下のような命名はコードベース全体の品質を下げるため、レビューで必ず指摘するべきです。

❌ data, info, util     ← 何も伝えていない
❌ temp, tmp            ← そのまま永続化される罠
❌ mgr, mng, svc        ← 過剰な略語
❌ foo, bar             ← テストコード以外で使わない
❌ getUserList vs getUsers ← 同義語の混在
❌ newUser, oldUser     ← 時間が経つと意味不明に

略語を使う場合は、プロジェクト固有の略語辞書(user = u は禁止、identifier = id はOK、など)を作ってチームで統一します。チームで禁止リストを共有しておくと、レビューでの指摘が楽になります。

「User / Member / Account / Customer 問題」(業界事例)

ある大手ECの案件で、同じ顧客情報を扱う機能なのに User / Member / Account / Customer の4つが混在していた、という話が語り草になっています。検索系APIも findUser / getMember / searchAccount の3系統が「同じテーブルを叩いていた」そうで、新しくジョインしたエンジニアは毎回「今回の要件はどれを直せば正解なのか」を先輩に聞いて回る必要があったとのことです。

3年目くらいの中堅が「User と Customer はどう違うんですか」と質問して、誰も明確に答えられず、その場で仕様書と業務用語集の齟齬が明らかになった、というやつもよく聞きます。原因はシンプルで、初期のDDDで言うところのUbiquitous Language(ユビキタス言語、チーム全員が同じ意味で使う共通語彙)が定義されていなかっただけ。各機能チームが別々にコードを書き、それぞれがドメイン用語をぶつけ合うように命名した結果、後から入った人間ほど「辞書を脳内で作る時間」が増えていきます。

規約とは結局、「この辞書を先に作って共有しておく仕事」に他なりません。同じ概念には一つの名前。用語辞書はコードを書き始める前に作ります。

Linter と Formatter

Linter は品質問題を検出するツール、Formatter は見た目を自動で整えるツールです。これらを使えば、「タブかスペースか」「セミコロンをつけるか」といった本質的でない議論を強制終了させられます。

言語LinterFormatter
JS / TSESLint / BiomePrettier / Biome
PythonRuff / PylintBlack / Ruff
Gogolangci-lintgofmt
RustClippyrustfmt
JavaCheckstyle / SpotBugsgoogle-java-format

高速・統合型の Biome / Ruff が本命です。CIで強制して議論を終わらせます。

Formatterの哲学

Prettier や gofmt のような現代のフォーマッタは、設定可能項目を「意図的に少なく」する哲学で設計されています。「好みで選べる項目が多いと、それが新たな議論の種になる」という経験則で、議論する余地そのものを潰しにいく設計です。

❌ タブ派 vs スペース派で毎回揉める
✅ Prettier / gofmt で決定、議論終了

チーム内で「このフォーマッタに従う」と決めた瞬間、スタイル議論はほぼ発生しなくなります。議論のコストをゼロにすることが目的で、見た目の好みは二の次です。

ツールの決定は「誰も100%満足しないが、全員が許容できる」レベルで十分です。

ディレクトリ構成

ディレクトリ構成は大きくレイヤー型機能型(Feature型)に分かれます。規模とチームの働き方で適切な方が変わります。

[Layer型]                [Feature型]
src/                    src/
├─ controllers/         ├─ users/
├─ services/            │  ├─ controller.ts
├─ repositories/        │  ├─ service.ts
├─ models/              │  └─ repository.ts
                        └─ orders/
                           ├─ ...
  • 小規模・初心者が多い → Layer型(層の役割が明確)
  • 中〜大規模・多チーム並列開発 → Feature型(機能ごとにコードがまとまり並列開発しやすい)

Feature型はモジュラーモノリスマイクロサービス化の前段階」として機能します。

コメントの原則

コメントは「WHY」(なぜ)を書くもので、「WHAT」(何を)を書くものではありません。名前で伝わることをコメントに書くのは、コードと矛盾した時に混乱の種になるだけです。

書くべき書かない
WHY(理由・背景)WHAT(コード読めば分かる)
非自明な制約・回避策名前で伝わる内容
外部仕様への依存作業履歴・担当者名
TODO(期限付き)古いコード(Gitに任せる)
❌ // iを1加算する
✅ // 配列末尾にセンチネルを置くので+1する(旧APIの制約)

コメントは腐ります。更新されずに残ったコメントは嘘になります。「最良のコメントは書かなくて済む命名」です。

PRレビューの原則

PR(プルリクエスト)レビューは品質を守る場であり、チームの学びの場でもあります。「レビュー文化がチームの技術力を決める」と言っていいほど効きます。

  • 責める場ではなく、学ぶ場として運営する
  • コードに対してコメントする(人を批判しない)
  • 小さなPRが速いレビューを生む(〜400行が目安)
  • 即応(24時間以内)で滞留を防ぐ
  • Nit(些細)/ Suggestion / Blocker を明示する

「Must / Should / Nit」のラベルをコメントに付けると、レビュワーの意図が明確に伝わります。

CODEOWNERSによるガードレール

決済・インフラ・セキュリティなどの重要ファイルは、必ず担当チームのレビューを経てマージする必要があります。GitHub の CODEOWNERS を使うと、特定ファイルの変更時に自動で担当者にレビュー依頼が飛びます。

# .github/CODEOWNERS
/src/payment/    @payment-team
/infra/          @sre-team
/.github/        @admin-team
/src/auth/       @security-team

機密部分や高難度コードを、知らない人が勝手にマージできない状態を作れます。マージ保護ルールと組み合わせれば、重要箇所のレビューが確実に走ります。

大規模プロジェクトではCODEOWNERSなしは事故の温床です。早期に設定するべきです。

Gitコミットメッセージ規約

チーム開発ではコミットメッセージの形式を統一することで、履歴の検索性やチェンジログの自動生成が容易になります。Conventional Commits が事実上の標準です。

feat: ユーザー検索APIを追加
fix: ログイン時のセッション固定脆弱性を修正
docs: READMEに環境変数の説明を追加
refactor: UserService を分割(責務過多のため)
chore: 依存ライブラリを更新

プレフィックス(feat / fix / docs / refactor / chore / test / perf 等)を付けることで、「何のコミットか一目で分かる」ようになります。Conventional Commits を採用すると、semantic-release で自動バージョニングができます。2018年にAngularチームが公開した規約が、2026年時点の事実上の標準です。

コード規約運用の段階別ロードマップ

規約は「READMEに書けば守られる」ほぼ幻想。CIで機械的に強制する段階を踏むのが定石です。

フェーズ導入ツールチェックタイミング目標時間
pre-commitBiome / Ruff / gofmt(Formatter)コミット時(ローカル)5秒以内
pre-pushESLint / Clippy(Lint)+ 型チェックpush直前30秒以内
PR全Lint + テスト + カバレッジGitHub push時10分以内
CODEOWNERS重要ファイル変更時に担当チームレビュー強制PR作成時自動
リリース前SemanticRelease(Conventional Commits)で自動バージョニングmerge時自動

Prettier・gofmt・Biome のような「意図的に設定を絞ったツール」が好まれるのは、「タブかスペースか」の議論を発生させない設計思想のため。Ruff は Python 界隈で ruff format + ruff check が Black + Flake8 + isort を置き換える勢いで急速に普及しています。

規約はCIで機械的に強制します。口頭・README・「気をつけます」は効きません。

命名・コード規約の鬼門・禁じ手

命名とスタイルで事故る典型を整理します。どれもチーム全体の生産性を削る地雷です。

禁じ手なぜダメか
同じ概念を複数の名前で扱う(User / Member / Account / Customer)新人が毎回「どれを直せば正解か」と聞き回る事態に
data / info / util / temp / mgr などの曖昧語意図ゼロ。temp が本番で永続化される事故の定番
チーム内で異なるLinter設定を使うPR差分がフォーマット差で埋もれ、本質的変更が見えなくなる
Linter警告を後でまとめて直す警告が100個を超えた時点で誰も見なくなる。ゼロ維持が現実解
略語を個人判断で決めるusr / custmrプロジェクト固有辞書なしの略語は読めなくなる
コミットメッセージを自由形式で書く履歴検索・チェンジログ生成・semantic-release が全て効かない
CODEOWNERSなしで決済・認証・インフラのコードをマージ知らない人が機密コードを勝手に変更できる状態。事故の温床
4層以上の深いディレクトリ階層importパスが長くなり、IDEの補完精度も落ちる
コメントにWHAT(何を)を書くコードと矛盾した時に嘘になる。書くべきはWHY(なぜ)
PRの粒度が1000行超レビューが形骸化。400行以下が目安、理想は100行

規約は議論するものではなく、ツールに任せるものです。Prettier vs タブ派の議論は技術的に終わっています。

AI時代の視点

AI駆動開発(バイブコーディング)が前提になると、命名とコード規約は「AIを縛る仕様書」として機能します。AIは制約がないと自由すぎる命名で無秩序なコードを生成しますが、Linter・Formatter・型を設定しておけば、AIがそれに従うコードだけを通せます。

AI時代に有利AI時代に不利
ESLint・Ruff等をCIで強制READMEに書いてあるだけの規約
Biome / Ruff等の統合ツール分散した設定ファイル
Conventional Commits等の機械可読規約自由形式のコミットメッセージ
CODEOWNERSで重要部分を保護誰でもマージできる状態

AIに生成させたコードは即座にLinter/Formatterを通して、ルール違反があれば自動修正する運用が鉄板です。コミットメッセージもAIがConventional Commits形式で生成できるため、規約ベースのワークフロー全体がAIと相性よく回ります。「規約=AIへの指示書」として設計するほど、AIは驚くほど正確なコードを書くようになります。

よくある勘違い

  • 「規約は書いてあれば守られる」 → READMEに書いただけでは絶対に守られません。CIで強制して初めて規約です
  • 「Linter警告は後でまとめて直す」 → 警告が増えるほど誰も見なくなります。ゼロを維持するのが現実解
  • 「命名は些細な問題」 → 命名のブレは時間とともに指数関数的にチームの生産性を削ります。初日に決めるべきこと
  • 「Prettierの設定で揉める」 → フォーマッタの設定議論は目的が逆。議論しないために導入しているツール

決めるべきこと — あなたのプロジェクトでの答えは?

以下の項目について、あなたのプロジェクトの答えを1〜2文で言語化してみてください。曖昧なまま着手すると、必ず後から「なぜそう決めたんだっけ」が問われます。

  • 命名規則(ケース・プレフィックス・禁止用語)
  • Linter / Formatterの選定と設定
  • ディレクトリ構成(Layer型 / Feature型)
  • コメント方針
  • PRサイズの目安・レビューSLA
  • CODEOWNERSの運用
  • Gitコミットメッセージ規約(Conventional Commits等)

最終的な判断の仕方

命名とコード規約の核心は「議論を自動化で終わらせること」です。命名やスタイルは一つひとつが小さい判断ですが、チーム全員が毎日触れるため、累計の議論コストは設計議論を圧迫するほど大きくなります。

優れた解決策は「どちらが正しいか」を議論することではなく、Linter・Formatterで機械的に決めてしまい、人間の頭を本質的な設計議論に解放することです。Prettier・gofmt・Biome・Ruff のように設定項目を絞ったツールが好まれる理由もここにあります。全員が100%満足する必要はなく、全員が許容できて議論が起きなければそれで十分です。

決定的な軸は「規約を機械可読にできているか」です。READMEに書かれた規約は守られません。守らせる唯一の方法は、LinterとFormatterとCIで強制することで、これは人間のためだけでなくAIへの制約としても決定的に効きます。

AIは制約がないと自由すぎる命名・無秩序なコードを生成しますが、規約が機械可読であれば、AI生成コードを自動で検査・修正できます。Conventional Commits・CODEOWNERS・型・Lintルール。これらはAIへの指示書として機能し、コード規約が整っているプロジェクトほどAI生成の精度が上がります。「人間のためのドキュメント」ではなく「機械が検証できる規約」を優先するのが鉄則です。

選定の優先順位をまとめると次の通りです。

  1. 命名は意図を表現する(名前 > コメント > ドキュメント)
  2. Linter / FormatterをCIで強制(議論より自動化)
  3. 規約を機械可読にする(CODEOWNERS / Conventional Commits)
  4. PRは小さく・レビューは速く(400行以内・24時間SLA

まとめ

本記事は命名とコード規約について、命名原則・Linter/Formatter・PRレビュー・CODEOWNERS・Conventional Commitsまで含めて解説しました。如何だったでしょうか。

議論を自動化で終わらせ、規約を機械可読にする。これがAI時代も含めた2026年のコード規約運用の現実解です。

次回はアプリケーションアーキテクチャカテゴリの最終記事、エラーハンドリング(Result型・Circuit Breaker・冪等性)について解説します。

シリーズ目次に戻る → 『生成AI時代のアーキテクチャ超入門』の歩き方

それでは次の記事も閲覧いただけると幸いです。