ストーリー
命名の原則
名前はコードの中で最も多く読まれる要素です。良い名前は、コメントがなくてもコードの意図を伝えます。
変数名
// 悪い命名
const d = new Date();
const n = users.filter(u => u.a);
const tmp = calculateTotal(items);
// 良い命名
const currentDate = new Date();
const activeUsers = users.filter(user => user.isActive);
const orderTotal = calculateTotal(items);
関数名
// 悪い命名:何をするのか不明
function process(data: User[]): void { /* ... */ }
function handle(event: Event): void { /* ... */ }
function doStuff(): void { /* ... */ }
// 良い命名:動詞 + 目的語で明確
function deactivateExpiredUsers(users: User[]): void { /* ... */ }
function logNavigationEvent(event: NavigationEvent): void { /* ... */ }
function calculateMonthlyRevenue(): number { /* ... */ }
ブーリアン変数
// 悪い命名
const flag = true;
const status = false;
// 良い命名:is/has/can/should で始める
const isActive = true;
const hasPermission = false;
const canDelete = user.role === 'admin';
const shouldRetry = attemptCount < MAX_RETRIES;
関数の長さとレベル
1つの関数は1つのことを
// 悪い例:複数のことを同時にやっている
function processUserRegistration(form: FormData): void {
// バリデーション
if (!form.email.includes('@')) throw new Error('Invalid email');
if (form.password.length < 8) throw new Error('Password too short');
// DB保存
const user = db.insert('users', { email: form.email, password: hash(form.password) });
// メール送信
smtp.send(form.email, 'Welcome!', `Hello ${form.name}...`);
// ログ記録
logger.info(`User registered: ${user.id}`);
}
// 良い例:1つの関数が1つの抽象レベルの処理
function processUserRegistration(form: FormData): void {
validateRegistrationForm(form);
const user = createUser(form);
sendWelcomeEmail(user);
logRegistration(user);
}
抽象レベルを揃える
// 悪い例:抽象レベルが混在
function generateReport(): string {
const data = this.reportService.fetchData(); // 高レベル
const formatted = data.map(d => { // 低レベル開始
const date = new Date(d.timestamp);
const y = date.getFullYear();
const m = String(date.getMonth() + 1).padStart(2, '0');
return `${y}-${m}: ${d.value.toFixed(2)}`; // 低レベル終了
});
return this.reportService.buildPdf(formatted); // 高レベル
}
// 良い例:同じ抽象レベルで統一
function generateReport(): string {
const data = this.reportService.fetchData();
const formatted = this.formatReportData(data);
return this.reportService.buildPdf(formatted);
}
コメントの使い方
書くべきコメント
// WHY(なぜ)を説明するコメント
// 税率は年度ごとに変わるため、ハードコードせずに設定から取得する
const taxRate = config.getTaxRate(fiscalYear);
// 非自明なビジネスルールの説明
// 30日以上経過した仮登録ユーザーは自動削除対象
const expiredUsers = users.filter(u =>
u.status === 'provisional' && daysSince(u.createdAt) > 30
);
// TODO/FIXME/HACK(技術的負債の明示)
// TODO: パフォーマンス改善 - N+1クエリを修正する (#1234)
書くべきでないコメント
// WHAT(何を)を繰り返すだけのコメントは不要
// ユーザーの年齢を取得する
const age = user.getAge(); // コードを読めばわかる
// 変更履歴をコメントで残す(Gitがある)
// 2024-01-15 田中: メール送信機能追加
// 2024-02-01 佐藤: バグ修正
まとめ
| ポイント | 内容 |
|---|---|
| 命名 | 意図が伝わる具体的な名前をつける |
| 関数の長さ | 1つの関数は1つのことをする |
| 抽象レベル | 同じ関数内で抽象レベルを揃える |
| コメント | WHYを書き、WHATは書かない |
チェックリスト
- 良い命名の原則を理解した
- 関数を1つの責任に絞る考え方を理解した
- 適切なコメントと不要なコメントの区別ができる
次のステップへ
Step 1 の最後は理解度チェックのクイズです。ここまで学んだコード品質の基礎知識を確認しましょう。
推定読了時間: 15分