リファクタリング & プロダクト化 — Vibe Coding 時代の心得
前半:動きを変えずに「読みやすく・直しやすく」するリファクタリングの原則。 後半:ブラウザだけで動く試作を、安全に段階を踏んで「プロダクト対応」にする実践ロードマップ。 通底する合言葉は「動きは変えない/小さく刻む/テストで守る」。ゴールは 人間(と AI)が短時間で把握できるコード。
1. 基本の原則(まず「人間が把握できる」コードに)
🧪 テストできる形に書く
- 「テストを書く」→ 「テストが“書ける”ように書く/直す」。
- テストしにくい=密結合・副作用まみれのサイン。テストのしやすさ=設計の良さの物差し。
- コツ:入力→出力が決まる純粋関数に切り出す/DB・API・時刻・乱数などの外部依存は引数で渡す(中で直に呼ばない)。
♻️ 重複を消す(DRY)
- コピペ=関数化/似た処理=共通化して関数化・抽象化。
- 同じ知識が2か所にあると直し忘れでバグる。「1つの知識は1か所」に集約。
- ⚠️ 「たまたま似てるだけ」を無理に1つにしない(早すぎる抽象化に注意)。目安は「3回目に出たら共通化を検討」。
📏 小さく保つ
- 1関数 20行以下 / 1ファイル 400行以下(目安)。
- 人間がひと目で把握できる大きさに。長い=責務を持ちすぎのサイン。
- コツ:長い関数は「意味のまとまり」で小関数に分け、良い名前で説明する(コメントより良い名前)。
🔌 疎結合にする(依存をなくす)
- 部品どうしの絡みが少ないほど、1か所の変更が他へ波及しない=安全に直せて、テストもしやすい。
- コツ:直接
newせず引数で受け取る(依存性注入)/具体でなく“約束(interface)”に依存する。
🔀 条件を整理する
- 深いネスト・複雑な
ifは読み違い=バグの温床。 - コツ:早期 return(ガード節)で入れ子を浅く/条件は名前付きにする(例:
const isAdult = age >= 18)。
2. Vibe Coding 時代に、さらに効くこと
AI(LLM)は、ざっくり言えば 「学習データをもとに“もっともらしい次のトークン”を、速く大量に生成する」 道具です。ここから素直に導けるのが、次の効きどころ。上の基本原則が さらに重要になる理由 でもあります(各項目=事実 → だから)。
🤖 速い・大量・でも間違える → 機械で検証する
- 事実:確率で生成するので、存在しない API や微妙にズレたコードを自信満々に出す(幻覚)。しかも人間より速く大量に積み上がる。
- だから:型(
anyを避ける)で矛盾を早期に落とし、テストで“動き”を固定し、diff を必ず読む。AI にテストを書かせてもよいが、「通るだけの空テスト」になっていないか人間が確認する。未読でマージしない。
🧠 見えるのはコンテキスト内だけ → 読める文脈を渡す
- 事実:AI は渡された範囲(コンテキスト)しか見られない。大きく散らかったコードは全体を把握できず、部分だけ見て矛盾を生む。
- だから:小さく・良い名前・型付きにするほど AI の精度も上がる(=人間向けの整理は、そのまま AI 向け)。
CLAUDE.md/AGENTS.md・doc で決まりと文脈を明示的に渡す。ライブラリ構成を先に指定すると、AI の共通化(DRY)が的確になる。
🌱 学習データに多いほど正確 → 枯れた定番を選ぶ
- 事実:学習データに多く登場する“枯れた”技術ほど AI は正確。マイナー・新しすぎる技術は知識が薄く、幻覚が増える。
- だから:ネットに情報が多い定番を選ぶ(AI がよく知っている=手戻りが減る)。
🪓 律速はレビュー帯域 → 小さく刻む
- 事実:生成は速いが、人間が読んで確かめられる量が律速。大きな差分ほど間違いが埋もれる。
- だから:細粒度のコミット/PRにして、各段でテスト・レビュー。大改造を一気にやらせない。すぐ戻せる粒度に。
🧾 AI は What を書くが Why を持たない → 意図と prompt を残す
- 事実:AI は指示から生成するだけで、その判断の理由は残らない。渡した指示(prompt)が実質のソース。
- だから:非自明な“なぜ”はコメント/PR 説明/決定記録に残す。AI に渡す md・指示もすべて git 管理(text=context がすべて)。
🛡✂️ AI は「動く」を優先 → セキュリティと“やりすぎ”を人間が締める
- 事実:AI は動くコードを優先し、鍵の直書き・危険な依存・不要な抽象/重複を出しがち。
- だから:秘密・インジェクション・依存(サプライチェーン)を点検し、要らない抽象・重複は削る(YAGNI)。「動く」で満足せず、“ここが危ない/ここが安全”を読む目を持つ。
3. 「気をつける」をやめて、ルールで自動化
原則は根性では続かない。linter / formatter / CI に落として、機械に指摘させる。レビューが「人の好み論争」でなく「客観ルール」になります。
- ESLint:
max-lines-per-function(関数の長さ)/max-lines(ファイル)/complexity(複雑さ)/max-depth(ネスト)/@typescript-eslint/no-explicit-any。 - 重複検出:
jscpdなどでコピペを可視化。 - Prettier:整形は自動(好みの議論をなくす)。
- CI:
lint/typecheck/testが通らなければマージをブロック。 - ルールは最初はゆるく、少しずつ厳しく。
4. いつ・どう進める?(リファクタリングのタイミング)
基本は「変更のたび、ついでに」。 リファクタリング専用の“いつか”を待たず、日々の変更に混ぜます。
- 🥾 変更のついでに:機能追加やバグ修正で触ったところを、来たときより少しきれいにして帰る(ボーイスカウト・ルール)。
- 🧱 機能追加の“前”に(準備):足しづらいと感じたら、先に整えてから足す。「変更を簡単にしてから、簡単に変更する」。
- 💡 理解できたとき:ぐちゃっとしたコードの意味がやっと分かったら、その理解を名前・構造に刻む。
- 👀 レビュー/PR のとき:気づいた小さな改善はその場で。
- 🔁 テストのリズム:TDD なら レッド → グリーン → リファクタ(テストが通った直後に整える)。
- ⚠️ 避けたい:ぜんぶ後回しにして「いつか大改造」。リスクが大きく、たいてい止まります。小さく継続が勝ち。
どう安全に?(動きを変えないための順番)
- テストで「いまの動き」を固定する(回帰テスト)。
- 小さく直す(1つの意図だけ)。
- テストが緑のままを確認 → コミット。
- くり返す。
迷ったら:「これは “動き” を変えていないか?」 と自問する。変えるなら、それはリファクタリングでなく 機能変更。分けて行う。
5. 実践:ブラウザだけの試作を「プロダクト対応」にする道のり
いま:全部ブラウザで動く(HTML/JS だけ・サーバーなし・データは各自の画面の中)。試作にはこれで十分。でも「人に使ってもらう・課金する」には足りません。
大事なのは、いきなり作り直さないこと。下の順で“地ならし”してから積み上げます。この順番自体に意味があります——各ステップが次のステップの前提になっているからです(前半=リファクタリング、後半=その土台の上にプロダクトの背骨を積む)。
- 🧪 現状のまま、ユニットテストを“書ける”ようにする
- まず動きを変えずに、テストが書ける形へ。これが以降の改造すべての安全網(回帰テスト)になる。
- テストしにくい場所は、次の分離で「どこを剥がすか」の地図にもなる。
- ♻️ 現状のまま、リファクタリングして整理・コンパクトに
- テストが緑なのを確認しながら、重複を消し・関数を小さく・条件を整理(§1)。動きは変えない。
- 見通しが良くなり、次の分離がやりやすくなる。
- ✂️ UI とロジックを分離する
- 画面(DOM・表示)と、判断・計算・データ処理(ロジック)を切り離す。
- なぜ先に? ロジックが画面に絡んだままだと、サーバーへ移せない。分離=「移せる形にする」準備であり、純粋関数化(§1)そのもの。
- 🖥 サーバーに置くべきロジックを、サーバーへ移す
- サーバーに置くべき=①秘密(API キー等。ブラウザに出したら盗まれる)②クライアントに任せられない判断(正誤・権限・お金に関わる計算)。
- 3 で分離済みだから、該当ロジックをまるごと移設できる。ブラウザは「お願いする側」に変わる。
- 🧷 サーバーのコードを TypeScript 化し、build / lint / CI を効かせる
- サーバーは壊れると全員に影響する“正本”。だから型・自動整形・静的チェック・CI で固める(§3)。
- 試作の緩さを、ここでプロダクト品質へ引き上げる。
- 🗄 ユーザーごとにデータを保存できるようにする
- サーバー+DB+ログイン(認証)を入れ、データに持ち主(
user_id)を持たせる。 - なぜここ? サーバー(4・5)と認証が無いと、「誰のデータか」を安全に保てない(ブラウザだけでは守れない)。
- サーバー+DB+ログイン(認証)を入れ、データに持ち主(
- 🛡💳 ここで初めて「ユーザーごとの分離」と「課金」が考えられる
- 分離:他人のデータを見られない・触れない(権限をサーバー側で強制。例:DB の行レベルセキュリティ=RLS)。
- 課金/使用量制限:誰が・どれだけ使ったかをサーバーで数えるから成立する。
- つまり分離も課金も、6 までの土台(サーバー+ per-user データ+認証)が前提。順番を飛ばすと必ず穴が空く。
🧭 この順番のキモ:安全網(テスト)→ 整理 → 分離 → 移設 → 硬化 → 永続化 → 制御(分離・課金)。 前半(1〜3)はリファクタリングそのもの、後半(4〜7)はその上にプロダクトの背骨(サーバーで「鍵・データ・お金」を守る)を積む流れ。作り直し(rewrite)ではなく、動かしながら段階的に——が、いちばん失敗しにくい道です。