リファクタリングとは?

公開日:
最終更新日:

イントロダクション:リファクタリングを一言で言うと? 🔧

リファクタリングとは、 「コードの外から見た動作は変えずに、内部の構造だけを良くすること」 です。

バグ修正や新機能追加とは違い、「機能を増やす・直す」のではなく、 同じ振る舞いを、より読みやすく・変更しやすい形で書き直す作業 だとイメージしてください。

「ちょっと読みにくい」「この辺がモヤっとする」と感じたコードを、 少しずつキレイに整えていく、 日常的な“お掃除と片付け”のような活動リファクタリングです。

1. なぜリファクタリングを学ぶ必要があるの?(現場ですぐ役立つ理由)

実務のコードは、一度書いて終わりではなく、 何度も仕様変更や機能追加が入るのが普通 です。

そのたびに場当たり的に書き足していると、コードが次のような状態になっていきます。

  • 同じような処理のコピペが増える
    ちょっとした仕様変更でも、あちこちのコピペを全部直さないといけない。
  • 1つの関数・クラスがなんでも屋になる
    条件分岐だらけで、「どこを直せばいいのか」が分かりづらくなる。
  • 変更が怖くなる
    動いてはいるけど、触ると壊れそうで誰も手を入れたがらない“ブラックボックス”が生まれる。

リファクタリングは、こうした 「技術的負債」 を少しずつ返済し、 「変更しやすい状態」を保ち続けるための基本テクニック です。 長く生きるシステムほど、リファクタリングの有無で差がつきます。

2. 「書き直し」「作り直し」とどう違うの?

似た言葉として「リライト」「全面改修」「作り直し」などがありますが、 リファクタリングはそこから目的が少し違う ことを押さえておきましょう。

  • リファクタリング
    外から見た動作・仕様は変えずに、コードの構造・名前・分割の仕方を改善する。 テストが通っていれば成功、とみなせる種類の変更。
  • 仕様変更・機能追加
    ユーザーから見た動きや画面が変わる。 要件定義の変更に対応するための、新しい振る舞いを足す・変える変更。
  • 全面的な作り直し
    アーキテクチャや技術選定ごと変えるような大きな変更。 動作も構造も大きく変わることが多い。

リファクタリング「仕様変更のついで」 ではなく、 それ自体が独立した作業(振る舞いは変えない、構造だけ改善する) として扱えると、 変更の影響範囲を考えやすくなり、失敗もしにくくなります。

3. どんなとき・どう進める?(安全に小さく進めるコツ) 🧪

リファクタリングは、 いきなり大規模にやろうとしない のがポイントです。 現場では次のような流れで、小さく安全に進めることが多いです。

  • 1. テスト(動作確認手段)を用意する
    自動テストが理想ですが、最低限「この操作をするとこう動く」といったチェック手順を決めておく。 リファクタリング後も同じ動作になるかを確かめるための「物差し」です。
  • 2. 気になる“におい”を見つける
    長すぎる関数・重複したコード・意味の分かりにくい名前など、 違和感のある箇所をピンポイントで選ぶ(コードの「悪いにおい」を嗅ぎ分けるイメージ)。
  • 3. 小さなステップで書き換える
    関数を1つに分割する、名前を変える、重複を1か所にまとめる…など、 一歩ごとにテストを回せるサイズ で変更する。
  • 4. こまめにコミットする
    テストが通った小さな変更ごとにコミットしておくことで、 いつでも戻せる安全ネットを確保する。

このサイクルを 機能追加やバグ修正の前後に少しずつ挟んでいく習慣 ができると、 時間をかけずに、でも着実にコードベースが整っていきます。

図解:プログラミングにおける「リファクタリング」

リファクタリングは、外から見た振る舞いを変えずに、 コードの内部構造を改善することです。読みやすさ・変更しやすさを高め、 バグを埋め込まないよう小さなステップで行います。

リファクタリングを理解する 3 つの視点

1. ゴール:振る舞いはそのまま、構造だけをきれいに

ユーザーから見た動きは変えずに、 「変更に弱いコード」から「変更に強いコード」へと作り替えるのが目的です。

Before:変更に弱いコード
  • 関数・クラスが長く、あちこちで同じ処理
  • UI と業務ルールがごちゃ混ぜ
  • 変数名・関数名から意図が読み取りづらい
After:変更に強いコード
  • 短く、役割ごとに分解された関数・クラス
  • ドメインの用語で名前がそろっている
  • UI / インフラとドメインの責務が分離

2. サイクル:小さなステップ+テストの繰り返し

リファクタリングいきなり大改造しないのが鉄則です。 テスト(自動テスト or 手動確認)を安全網にして、細かい変更を積み重ねます。

テストを整える
現状の振る舞いを固定
小さく書き換える
1〜2 手の変更に限定
テストを回して確認
通ったらコミット

この 3 ステップを何度もぐるぐる回しながら、少しずつ構造を整えていきます。

3. 対象:どこをどう整えるか

リファクタリングは「きれいにする」ではなく、 狙いを決めてコードの形を変える作業です。代表的な的(まと)は次の 3 つです。

名前を整える
  • 関数・変数・クラス名を意図が伝わる言葉に
  • 意味の重複やあいまいな略語をなくす
構造を整理する
  • 長い関数を分割(メソッド抽出など)
  • 重複ロジックを共通化
責務の境界を引き直す
  • UI とドメインの処理を分ける
  • クラス・モジュールの責務を 1 つに寄せる
リファクタリングは、バグ修正や新機能追加とは別に、 「今ある振る舞いを守りながら、あとから変えやすい形に整える」ための作業です。 テストを安全網に、小さな変更を積み重ねて、ドメインが見えやすいコードに近づけていきます。

JavaScriptで見る「リファクタリング」の例

ここでは、同じ「データ取得 → 計算 → 表示の整形」を題材に、 リファクタリング前(Before)リファクタリング後(After)を見比べます。 外から見た挙動は変えずに、コードの内部構造だけを整えるイメージです。

Before:1つのイベントハンドラに「取得・計算・表示」がベタ書きされたコード

クリックイベントの中に、データ取得合計計算フォーマット描画がすべて押し込まれています。 動きは分かりやすい反面、仕様変更やテストには弱い形です。


// 今日の売上合計を表示するボタン
document.getElementById('show-today-sales').addEventListener('click', function () {

	const resultEl = document.getElementById('today-sales-result');
	resultEl.textContent = '読み込み中...';

	// API から全売上一覧を取得
	fetch('/api/sales')
		.then(function (res) {
			if (!res.ok) {
				throw new Error('API error');
			}
			return res.json();
		})
		.then(function (data) {

			// 今日の日付文字列を作成(YYYY-MM-DD)
			const now = new Date();
			const yyyy = now.getFullYear();
			const mm = ('0' + (now.getMonth() + 1)).slice(-2);
			const dd = ('0' + now.getDate()).slice(-2);
			const todayStr = yyyy + '-' + mm + '-' + dd;

			// 今日の売上だけに絞って合計
			let total = 0;
			for (let i = 0; i < data.length; i++) {
				const row = data[i];
				if (row.date === todayStr) {
					total += row.amount;
				}
			}

			// 金額フォーマットをその場で実装
			const formatted = total
				.toString()
				.replace(/\B(?=(\d{3})+(?!\d))/g, ',');

			// 結果の HTML をここで直接組み立て
			if (total === 0) {
				resultEl.innerHTML = '<p>本日の売上はありません。</p>';
			} else {
				resultEl.innerHTML =
					'<p>本日の売上合計:<strong>' +
					formatted +
					'</strong> 円</p>';
			}
		})
		.catch(function (err) {
			console.error(err);
			resultEl.innerHTML =
				'<p class="error">売上の取得に失敗しました。</p>';
		});
});
			

イベントハンドラの中にすべての処理が詰め込まれているため、 「対象期間を変える」「表示形式を変える」といった変更のたびに この長い関数を直接いじる必要があります。

After:振る舞いはそのまま、中身を分割したコード

同じ「今日の売上合計を表示する」機能ですが、 日付計算集計ロジック描画処理を それぞれ独立した関数に切り出しています。 結果として、テスト・再利用・仕様変更がしやすい形になります。


// ---- ドメイン寄りの小さな関数群 --------------------------

function formatDateYYYYMMDD(date) {
	const yyyy = date.getFullYear();
	const mm = ('0' + (date.getMonth() + 1)).slice(-2);
	const dd = ('0' + date.getDate()).slice(-2);
	return `${yyyy}-${mm}-${dd}`;
}

function formatCurrencyJPY(amount) {
	return amount
		.toString()
		.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

/**
 * 売上配列から、指定した日付の合計金額を計算する
 * @param {Array<{date: string, amount: number}>} sales
 * @param {string} targetDate YYYY-MM-DD
 */
function calculateTotalSalesForDate(sales, targetDate) {
	return sales
		.filter((row) => row.date === targetDate)
		.reduce((sum, row) => sum + row.amount, 0);
}

/**
 * API から全売上一覧を取得する
 * @returns {Promise<Array<{date: string, amount: number}>>}
 */
function fetchAllSales() {
	return fetch('/api/sales').then((res) => {
		if (!res.ok) {
			throw new Error('API error');
		}
		return res.json();
	});
}

/**
 * 計算結果を DOM に描画する
 * @param {HTMLElement} container
 * @param {number} total
 */
function renderTodaySales(container, total) {
	if (total === 0) {
		container.innerHTML = '<p>本日の売上はありません。</p>';
		return;
	}
	const formatted = formatCurrencyJPY(total);
	container.innerHTML =
		'<p>本日の売上合計:<strong>' +
		formatted +
		'</strong> 円</p>';
}

// ---- UI 側:イベントハンドラは「流れ」を組み立てるだけ --------

document.getElementById('show-today-sales').addEventListener('click', function () {
	const resultEl = document.getElementById('today-sales-result');
	resultEl.textContent = '読み込み中...';

	const todayStr = formatDateYYYYMMDD(new Date());

	fetchAllSales()
		.then((sales) => {
			const total = calculateTotalSalesForDate(sales, todayStr);
			renderTodaySales(resultEl, total);
		})
		.catch((err) => {
			console.error(err);
			resultEl.innerHTML =
				'<p class="error">売上の取得に失敗しました。</p>';
		});
});
			

イベントハンドラは「読み込み中表示 → データ取得 → 集計 → 描画」という 処理の流れだけを表現し、 個々のロジックは専用の関数に追い出されています。 「対象日付を変える」「期間合計にする」「グラフ表示にする」といった変更も、 関数単位で見通しよく修正できます。

まとめ:リファクタリング習慣のポイント

  • リファクタリングは、 「動作を変えずに、コードの構造だけを良くする」 ための作業です。
  • 放置すると増えていく 技術的負債(読みづらさ・変更しづらさ) を、少しずつ返していくための基本テクニックです。
  • 仕様変更や作り直しと違い、 振る舞いは変えない ことが前提なので、 テスト(動作確認の物差し)と「小さなステップ」が重要になります。
  • 日々の開発の中で「モヤっとしたら、まず小さく整える」という リファクタリング習慣を身につけることで、 長く変化し続けるシステムを支えやすくなります。

まずは、 「動作は変えずに、ちょっとだけ読みやすく・直しやすくする」 ところから始めてみると、 リファクタリングの感覚がつかみやすくなります。

このページの著者

もちもちみかん(システムエンジニア)

社内SEとしてグループ企業向けの業務アプリを要件定義〜運用まで一気通貫で担当しています。

経験:Webアプリ/業務システム

得意:PHP・JavaScript・MySQL・CSS

個人実績:フォーム生成基盤クイズ学習プラットフォーム

詳しいプロフィールはこちら!  もちもちみかんのプロフィール

もちもちみかん0系くん
TOPへ

もちもちみかん.comとは


このサイトでは、コーディングがめんどうくさい人向けのお助けツールとして、フォームやCSSをノーコードで生成できる、
 もちもちみかん.forms
 もちもちみかん.css1
 もちもちみかん.css2
と言ったジェネレーターを用意してます。

また、このサイトを通じて、「もちもちみかん」のかわいさを普及したいとかんがえてます!