ウェブエンジニア問題集

伝わるコードとドキュメント — 命名・コメント・文章の技術

「命名」はコードの可読性を左右する最も基本的な要素です。 適切な名前をつければコードは読みやすくなり、不適切な名前はバグや誤解の温床になります。

しかし、伝える技術はコードの中だけに留まりません。設計書・READMEなどのドキュメントでも「誰に、何を、どう伝えるか」を意識しなければ、書いたのに読まれない・読んだのに伝わらないドキュメントが量産されます。

この章では、命名・コメント・ドキュメントの書き方を横断的に整理します。

学習者学習者

変数名って、短い方が楽だしタイプも速いけど…チームで書くときは困るよね?

命名規則の具体的なパターン(ケーシング、プレフィックス、用語集の運用など)は現在執筆中です。

コードは自己文書化される? — 賛否を整理する

コードを読んで考える人

「良いコードはそれ自体がドキュメントだ(Self-documenting code)」——この主張はソフトウェア開発で長く議論されてきました。

賛成派の立場

  • 適切な変数名・関数名をつければ、コードを読むだけで何をしているかは分かる
  • ドキュメントはコードと乖離するが、コード自体は常に最新の「仕様書」である
  • ドキュメントに時間を使うより、コードの可読性を上げることに投資すべき
const activeUsers = users.filter(user => user.isActive);
const sortedByLastLogin = activeUsers.sort(
  (a, b) => b.lastLoginAt.getTime() - a.lastLoginAt.getTime()
);

このコードは変数名だけで「アクティブなユーザーを最終ログイン日時の降順でソートしている」と読み取れます。

反対派の立場

  • コードは what(何をしているか) を表現できるが、why(なぜそうしたか) は表現できない
  • ビジネスルールの背景、却下した代替案、既知の制約はコードに埋め込めない
  • 関数名で意図を伝えるにも限界がある(命名だけで複雑な前提条件は伝わらない)
  • システム全体のアーキテクチャや、コンポーネント間の関係はコードを1ファイルずつ読んでも見えてこない
const TIMEOUT_MS = 3000;

この定数がなぜ3000ミリ秒なのか——「外部APIのSLAが5秒でリトライを1回含めるため」という判断は、コードからは読み取れません。

結論

どちらも正しく、どちらも不完全です。実務では両方を組み合わせます。

  • コードの可読性を最大限に高めたうえで、コードだけでは伝わらない情報をドキュメントに書く
  • what はコードに任せ、why と how(全体像)をドキュメントに書く
学習者学習者

結局、どこまでコードに任せて、どこからドキュメントに書けばいいの?

先生先生

「半年後の自分がこのコードを見たとき、変数名だけで判断の理由まで分かるか?」と自問してみて。分からないなら、それはドキュメントに書くべき情報だよ。

コメントは不要か? — 賛否を整理する

「自己文書化コード」の議論と密接に関連するのが「コードコメントは必要か」というテーマです。

「コメント不要」派の主張

  • コメントが必要だと感じたら、まずコードをリファクタリングすべき
  • コメントはメンテされず、古い情報が残って読者を誤解させる
  • コメントはコードの「臭い(code smell)」——コードが複雑すぎる兆候
// ❌ コードを日本語に訳しただけのコメント
// ユーザーの年齢が18以上かチェックする
if (user.age >= 18) { ... }

このコメントはコードと同じ情報を繰り返しているだけで、何の価値もありません。

「コメント必要」派の主張

  • 意図の記録: なぜこの実装を選んだか、他にどんな選択肢があったか
  • 警告: このコードを変更すると何が壊れるか
  • TODO/FIXME: 既知の技術的負債の明示
  • 正規表現や複雑なアルゴリズム: コードだけでは意図を読み取れないケース
  • 法的・ビジネス上の制約: コードの背後にある非技術的な理由
// ⭕ 価値のあるコメント
 
// 消費税の端数は切り捨て(2019年の経理部門との取り決め、変更時は経理に確認)
const tax = Math.floor(price * TAX_RATE);
 
// Safariのバグ回避(https://bugs.webkit.org/show_bug.cgi?id=xxxxx)
// Safari 16未満ではこのAPIが期待通りに動作しない
element.scrollIntoView({ behavior: 'instant' });

書くべきコメントと書かないべきコメント

書くべきコメント書かないべきコメント
Why — なぜこの実装を選んだかWhat — コードが何をしているかの翻訳
Warning — 変更すると壊れる箇所自明な処理の逐語的な説明
外部制約 — ビジネスルール、バグ回避古くなって実態と合わないコメント
複雑なロジック — 正規表現、ビット演算変数名を改善すれば不要になるコメント

知識の呪い — 「自分には分かる」が生む落とし穴

知識の呪いのイメージ
自分が知っていることを、相手も知っていると無意識に思い込む

知識の呪い(Curse of Knowledge) とは、ある知識を身につけた人が「それを知らない状態」に戻れなくなる認知バイアスです。 設計書を書くとき、これが最大の敵になります。

書き手にとっては当然の前提でも、読み手にとっては未知の専門用語かもしれません。 「この程度は分かるだろう」と省略した1行が、読者にとっては致命的な情報の欠落になることがあります。

読者は誰か? — ドキュメントの2つの読者像

設計書の読者は大きく2種類に分かれます。それぞれニーズが異なるため、「誰に向けて書くか」を最初に決めないと中途半端なものになります。

読者求めている情報書き方のポイント
エンドユーザー何ができるか、どう使うか専門用語を避ける。ステップバイステップで手順を示す。スクリーンショットを多用する
開発者どう動くか、どう拡張するか正確な用語を使う。コード例を載せる。設計判断の「なぜ」を記す

同じ機能でも、ユーザー向けマニュアルと開発者向けドキュメントでは文体・粒度・省略してよい前提知識がまるで違います。

❌ 読者を意識しない例:
「OAuthのリダイレクトURIをコールバックエンドポイントに設定してください」
→ エンドユーザーには何のことか分からない

⭕ エンドユーザー向け:
「ログインボタンを押すと、Googleアカウントの選択画面が表示されます。
アカウントを選ぶとアプリに戻り、自動的にログインが完了します」

⭕ 開発者向け:
「OAuth 2.0 Authorization Code Flowを使用。
コールバックURL: /api/auth/callback/google
トークンはサーバーサイドで検証し、セッションCookieに変換する」

サンプルコードの書き方 — 2つの種類と省略の技術

設計書やドキュメントに含めるサンプルコードには2つの種類があります。目的を混同すると、読者にとってノイズだらけのドキュメントになります。

1. 実行可能なサンプルコード

コピー&ペーストしてそのまま動くコード。チュートリアルやクイックスタートで使います。

import express from 'express';
 
const app = express();
app.use(express.json());
 
app.get('/api/hello', (req, res) => {
  res.json({ message: 'Hello, World!' });
});
 
app.listen(3000, () => {
  console.log('Server running on port 3000');
});

読者はこれをコピーしてすぐに結果を確認できます。依存関係のインストール手順も併記するのが親切です。

2. 説明用のサンプルコード

特定の概念やパターンを説明するためのコード断片。APIリファレンスや設計ガイドで使います。 すべてのimportや設定を含める必要はなく、読者が注目すべき部分だけを示します。

app.get('/api/users/:id', async (req, res) => {
  const user = await db.users.findById(req.params.id);
  if (!user) {
    return res.status(404).json({ error: 'USER_NOT_FOUND' });
  }
  res.json(user);
});

長いコードは省略する

サンプルコードが長くなりすぎると、読者はどこに注目すべきか分からなくなります。 本題と関係ない部分は省略記号...)で省き、焦点を絞ります。

class UserService {
  // ... コンストラクタやDI設定は省略
 
  async updateProfile(userId: string, data: UpdateProfileDto) {
    const user = await this.userRepo.findById(userId);
    if (!user) {
      throw new NotFoundException('User not found');
    }
 
    // ... バリデーション処理は省略
 
    return this.userRepo.save({ ...user, ...data });
  }
 
  // ... 他のメソッドは省略
}
種類目的省略使う場面
実行可能コピーして動かすしないチュートリアル、クイックスタート
説明用概念・パターンを示すするAPIリファレンス、設計ガイド

ちゃんと使うためのポイント

  • 命名はコードの可読性を決める最も基本的な要素——省略より明確さを優先する
  • コードの可読性を最大化したうえで、コードだけでは伝わらない情報をドキュメントに書く
  • コメントは what(何をしているか)ではなく why(なぜそうしたか)を書く
  • コメントアウトコードは残さない——Gitの履歴から復元できる
  • ドキュメントは「誰が読むか」で粒度と文体を変える——知識の呪いに注意する
  • サンプルコードは「実行可能」と「説明用」を使い分け、省略時は何を省いたか明記する

次の章では、コードの整理に直結するディレクトリ構成を解説します。