メインコンテンツまでスキップ

第5章:コードのニオイ入門(やばさを嗅ぎ分ける)👃💥

この章でできるようになること 🎯✨

  • 「これ…ヤバくなりそう🥺」なコードを早めに嗅ぎ分けできるようになる🐶👃
  • ニオイを見つけたときに、**何が困るのか(未来の痛み)**を言葉にできる🗣️💡
  • VS Code と静的解析(ESLintなど)とAIを使って、ニオイを見逃しにくくする習慣が作れる🔍🤖✨

Untangling Ribbon


1) そもそも「コードのニオイ」って何?🧸🌸

コードのニオイ(Code Smell)は、**表面に出ている「怪しいサイン」**のことだよ👀⚠️ それ自体がバグとは限らないけど、もっと深い問題が隠れてるかもって教えてくれる合図なの✨ (martinfowler.com)

そして大事なのがこれ👇

  • ニオイ=「有罪判決」じゃない🙅‍♀️
  • ニオイ=「点検しよっか」のサイン✅

SonarQubeの用語でも、Code Smellは「保守性を下げて、コードを分かりにくくする問題」って位置づけだよ📉🧹 (Sonar ドキュメンテーション)


2) ニオイを放置すると、未来でこうなる😇💣

ニオイを放置すると、だいたい次のどれかが起きるよ〜😵‍💫

  • 仕様追加のたびに、同じ場所を怖くて触れない🥶
  • 直したら別のところが壊れて、デバッグ地獄🕳️🐛
  • 「誰が読んでも分からん」になって、自分ですら辛い😭
  • テストを書きたくても書けず、確認が手作業になる🧪➡️😱

ニオイは「今の痛み」より、変更が来たときの痛みを増幅する装置だと思ってOK💥🔁


3) まずは王道ニオイ四天王 😈👑

ここからは、超頻出のニオイを「症状 → 未来の痛み」で覚えよ〜📝✨

A. 長すぎ関数 🐍📏

症状:1つの関数がやること多すぎ(計算・保存・通知・ログ…全部) 未来の痛み:ちょい修正で全体が壊れそう、テストしづらい😇💥

B. 巨大クラス(神クラス)🗿🏛️

症状:OrderServiceが何でも屋(料金・在庫・DB・通知) 未来の痛み:変更理由が増えすぎて、毎回怖い😱

C. if地獄 / switch地獄 🌋🔁

症状:条件分岐が増殖して、読みながら迷子🧭 未来の痛み:追加するたびに分岐が壊れて事故る🚑

D. コピペ地獄 📋📋📋

症状:似たコードがあちこちに… 未来の痛み:修正漏れが必ず出る(Shotgun Surgery系)🧨


4) TypeScriptで起きがちな「TS特有ニオイ」🧠🌀

TSは型がある分、型まわりのニオイが出やすいよ〜!

  • any で逃げる(型安全の放棄)🫠
  • 型アサーション as XXX の乱用(“ほんとに?”問題)🤥
  • string で状態や種類を表現(例:"cash" | "card" をただの string にする)=プリミティブ執着🪨
  • null / undefined チェックが散らばる(nullable地獄)☁️
  • 返り値が「成功したの?失敗したの?」曖昧(例外/Result型の整理不足)😵

※ちなみに、現時点のTypeScriptのnpm最新版は 5.9.3 だよ📦✨ (npm) (この章の内容はバージョンに依存しないけど、「型で守る」流れはこの先ずっと大事!)


5) 実験:わざと「ニオイコード」を書いてみよう 🧪👃💥

Campus Café(ミニ題材)で、注文確定を一気にやる関数をわざと作るよ☕️📦 目的は「直す」じゃなくて、ニオイを発見する練習ね🔍✨

// わざとニオイだらけ!教材用 🧪
// やってること:合計計算 → 割引 → 支払い方法で分岐 → 保存 → 通知 → ログ
export function checkout(order: any, payment: any, coupon: any) {
let total = 0;

// 商品合計(nullチェックも雑)
for (const item of order.items) {
total += item.price * item.qty;
}

// クーポン(if地獄の芽)
if (coupon) {
if (coupon.type === "student") {
total = total * 0.9;
} else if (coupon.type === "rain") {
total = total - 100;
} else if (coupon.type === "set") {
if (order.items.length >= 3) total = total - 200;
}
}

// 支払い(またif)
if (payment.method === "cash") {
if (payment.cash < total) {
return { ok: false, message: "お金たりない" };
}
// お釣り計算
const change = payment.cash - total;
console.log("change:", change);
} else if (payment.method === "card") {
// なんか外部呼ぶ想定(詳細が混ざる)
console.log("call card api...");
} else if (payment.method === "paypay") {
console.log("call paypay api...");
}

// 保存(詳細が混ざる)
console.log("save to db:", order.id, total);

// 通知(詳細が混ざる)
if (order.notifyEmail) {
console.log("send email:", order.email);
}

return { ok: true, total };
}

ミニ課題①:ニオイに付箋を貼る気持ちでチェック🧷👀

上のコードを見て、ニオイっぽい場所にコメントを付けるつもりで数えてみてね😊 目標:8個以上見つけられたら勝ち🎉✨

ヒント👇

  • 「責務が混ざってない?」🧩
  • 「条件分岐、増えそうじゃない?」🔁
  • 「型が弱すぎない?」🫠
  • 「外部詳細(DB/API/通知)がロジックに混ざってない?」📡

6) ニオイ発見の“型”を作ろう:ニオイ質問リスト 📝👃

コードを読むとき、これを自分に質問すると嗅ぎ分けが上手くなるよ🐶✨

✅ ニオイ質問 10連発

  1. この関数、やってること3つ以上ない?🍱
  2. 変更理由が複数ありそう?(仕様追加の想像)🔮
  3. if / switch が増えたら破綻しそう?🌋
  4. 同じロジックが他にもありそう?📋
  5. 変数名が「a」「tmp」「data」っぽくて意味不明?😵
  6. anyas安心感ゼロになってない?🫠
  7. “文字列”で状態を表しすぎてない?🧵
  8. null/undefined 対応が散らばってない?☁️
  9. 依存(DB/API)がロジックに直混ぜじゃない?🥣
  10. テスト書くとしたら、どこが邪魔?🧪🧱

7) VS Code と静的解析で「鼻を強化」しよ👃🦾✨

人間の嗅覚だけだと見落とすから、ツールの鼻も借りよ〜🤝

  • TypeScriptの型エラー/警告:ニオイの予兆になる👀
  • ESLint:怪しいパターン(複雑すぎ、未使用、危険な書き方)を拾いやすい🧹
  • ちなみにESLintは v10 が2026年1月頃を目標に進んでて、大きめ変更も入る予定だよ📦⚠️ (ESLint) → だからこそ「ツールの指摘=絶対」じゃなく、理由を理解する姿勢が大事😊✨

8) AI(Copilot/Codex系)でニオイを見つけるコツ 🤖🔍✨

AIは「嗅ぎ分け補助」にはめっちゃ使えるよ!ただし、鵜呑み禁止ね🙅‍♀️🍭

使えるプロンプト例 🧠💬

次のTypeScriptコードを読んで、コードのニオイ(責務混在、条件分岐増殖、型の弱さ、重複、依存の混ざり)を
「ニオイ名」「どの行/箇所」「将来の痛み」「最小の改善案(今は直しすぎない)」の形式で箇条書きにして。
このコードをユニットテストしづらくしている要因を列挙して。
テストしやすくするための“境界(分離ポイント)候補”も提案して。

AIを使うときのルール3つ 🐣✅

  • ニオイの理由を説明できない提案は採用しない🙅‍♀️
  • ② 変更は一気にやらず、小さく(差分レビューしやすく)✂️
  • ③ “綺麗すぎる抽象化”を急に入れない(それ別章でやる)🧊

9) ミニ課題②:ニオイを「未来の変更」で説明してみよう🔮📝

さっきの checkout に対して、次の変更が来たらどうなるか想像してみてね😊

  • 割引が「学割・雨の日・誕生日・曜日・紹介」…増える🎟️
  • 支払いが「現金・カード・PayPay・交通系・後払い」…増える💳
  • 通知が「メール・アプリ通知・LINE」…増える🔔

書くこと(短くてOK)✍️

  • 「どこが地獄になりそう?」😇
  • 「なぜ地獄?(if増殖?責務混在?)」🌋
  • 「境界として分けられそうなのはどこ?」✂️🧩

10) 章末チェック(できたらOK)✅🎉

  • ニオイはバグじゃなく「点検サイン」って説明できる👃✨ (martinfowler.com)
  • 長すぎ関数 / 巨大クラス / if地獄 / コピペ地獄 を見つけられる😈
  • TS特有ニオイ(any乱用、型の弱さ、文字列状態など)を1つ以上言える🧠
  • ニオイを「未来の変更」で語れる🔮🗣️

次章の予告 🧫✅

次は「テストしにくい=設計が苦しい」あるあるを体験するよ〜🥺 ニオイを“確信”に変える武器が、テストだよ🧪🧡