ブログ一覧
Clean Code関数設計リファクタリング

Clean Codeの第3章「関数」を1時間で体感する方法

Robert C. Martinの『Clean Code』第3章「関数」は、多くの開発者が「読んだはずなのに身についていない」章No.1です。

理由はシンプル。教科書の例と自分のコードが結びついていないから。

第3章の核心

Uncle Bobは第3章で、良い関数の特徴をこう定義しています。

  1. 小さく書け — 関数は20行以内
  2. 1つのことだけを行え — 単一責任の原則(SRP)
  3. 抽象レベルを統一せよ — 高レベルと低レベルのロジックを混ぜるな
  4. 引数は少なく — 理想は0、多くても3つまで
  5. 副作用を持つな — 関数名が示す以外のことをするな

読めば「当たり前じゃん」と思います。でも実際に自分のコードを見返すと、どうでしょうか?

よくあるコード

async function processUser(userId: string) {
  const user = await db.user.findUnique({ where: { id: userId } });
  if (!user) throw new Error("not found");

  // メール送信
  await sendgrid.send({
    to: user.email,
    subject: "Welcome",
    html: `<p>Hello ${user.name}</p>`,
  });

  // ログ記録
  await db.auditLog.create({
    data: { userId, action: "welcome_sent", timestamp: new Date() },
  });

  // キャッシュ更新
  await redis.set(`user:${userId}:welcomed`, "1", "EX", 86400);

  return user;
}

この関数、何をしていますか?

  • ユーザー取得
  • メール送信
  • 監査ログ記録
  • キャッシュ更新

4つのことをしています。関数名はprocessUser— 何も伝わりません。

Clean Code視点でのリファクタリング

async function sendWelcomeToUser(userId: string) {
  const user = await fetchUser(userId);
  await sendWelcomeEmail(user);
  await recordWelcomeSent(user.id);
  return user;
}

高レベルの関数は「何をするか」だけを記述。詳細は下位の関数に任せる。これが抽象レベルの統一です。

CodeSenseiで体感する

このレッスンをCodeSenseiで受けると、AIがあなたの実際のコードを題材に同じ原則を解説してくれます。

架空のUserクラスの例ではなく、あなたが昨日書いたprocessOrderupdateProfileを題材に「ここから Clean Code 第3章が体感できる」と教えてくれます。


CodeSenseiを試す →

自分のコードで学んでみませんか?

CodeSenseiは無料で始められます。

無料で始める