📖 読了目安 約9分
この記事の目次

Step6: リファクタリングする

コードが動くようになったら、「より良いコード」にするためのリファクタリングを検討します。ただし、1年目は過度なリファクタリングは避け、基本的な改善に留めることが重要です。

リファクタリングとは

リファクタリング = 外部から見た動作を変えずに、コードの内部構造を改善すること

目的:
✅ 読みやすくする
✅ 保守しやすくする
✅ バグを減らしやすくする

注意:
❌ 機能を追加することではない
❌ パフォーマンスを上げることではない(別の話)

なぜリファクタリングが必要なのか

「動くコード」と「良いコード」は違う

動くコード:
- とりあえず期待通りの結果が出る
- 自分だけが分かる

良いコード:
- 期待通りの結果が出る
- 誰が読んでも分かる
- 修正しやすい
- バグが入りにくい

1年目の現実

注意: 1年目は「完璧なコード」を目指す必要はありません

1年目の優先順位:
1. 動くコードを書く(最優先)
2. 基本的な読みやすさを確保
3. 明らかな問題を修正

やりすぎ注意:
❌ 完璧なリファクタリングを目指す
❌ 先輩が書いたコードを勝手に大きく変える
❌ 時間をかけすぎる

1年目で押さえるべきリファクタリング

改善1: 意味のある名前に変更する

なぜ重要か: 名前が悪いと、コードを読むたびに「これは何?」と考える必要がある

// Before: 何のことか分からない
int d = 30;
String s = "John";
List<Order> list = getOrders();

// After: 意味が明確
int daysUntilExpiry = 30;
String customerName = "John";
List<Order> pendingOrders = getOrders();

ポイント:

  • 略語を避ける(cntcountbtnbutton
  • 何を表しているか分かる名前にする
  • 長くなっても意味が伝わる方が良い

改善2: マジックナンバーを定数に

なぜ重要か: 数字だけでは意味が分からず、修正時に漏れが生じる

// Before: 30って何?0.1って何?
if (days > 30) {
    discount = price * 0.1;
}

// After: 意味が明確
private static final int PREMIUM_THRESHOLD_DAYS = 30;
private static final double PREMIUM_DISCOUNT_RATE = 0.1;

if (days > PREMIUM_THRESHOLD_DAYS) {
    discount = price * PREMIUM_DISCOUNT_RATE;
}

ポイント:

  • 意味のある名前をつける
  • 同じ値を複数箇所で使う場合は特に重要
  • 仕様変更時に1箇所の修正で済む

改善3: 長いメソッドを分割する

なぜ重要か: 長いメソッドは理解が難しく、テストも困難

// Before: 100行のメソッド
public void processOrder(Order order) {
    // バリデーション(20行)
    ...
    // 在庫チェック(15行)
    ...
    // 計算処理(30行)
    ...
    // DB登録(20行)
    ...
    // 通知送信(15行)
    ...
}

// After: 役割ごとに分割
public void processOrder(Order order) {
    validateOrder(order);
    checkStock(order);
    calculateTotal(order);
    saveToDatabase(order);
    sendNotification(order);
}

private void validateOrder(Order order) {
    // バリデーション処理
}

private void checkStock(Order order) {
    // 在庫チェック処理
}
// ...

ポイント:

  • 1つのメソッドは1つの責任
  • 目安は20〜30行以内
  • メソッド名で何をするか分かるように

改善4: ネストを減らす

なぜ重要か: 深いネストは読みにくく、バグを見逃しやすい

// Before: 深いネスト
public void process(Order order) {
    if (order != null) {
        if (order.getItems() != null) {
            if (!order.getItems().isEmpty()) {
                for (Item item : order.getItems()) {
                    if (item.getStock() > 0) {
                        // 処理
                    }
                }
            }
        }
    }
}

// After: 早期リターンでフラットに
public void process(Order order) {
    if (order == null) return;
    if (order.getItems() == null) return;
    if (order.getItems().isEmpty()) return;

    for (Item item : order.getItems()) {
        if (item.getStock() <= 0) continue;
        // 処理
    }
}

ポイント:

  • 異常系は早期リターン
  • ループ内の条件はcontinueで抜ける
  • ネストは2〜3階層が目安

改善5: 重複コードをまとめる

なぜ重要か: 同じコードが複数あると、修正漏れが発生する

// Before: 同じ処理が重複
public void createUser(User user) {
    if (user.getName() == null || user.getName().isEmpty()) {
        throw new ValidationException("名前は必須です");
    }
    // ...
}

public void updateUser(User user) {
    if (user.getName() == null || user.getName().isEmpty()) {
        throw new ValidationException("名前は必須です");
    }
    // ...
}

// After: 共通メソッドに抽出
public void createUser(User user) {
    validateUserName(user);
    // ...
}

public void updateUser(User user) {
    validateUserName(user);
    // ...
}

private void validateUserName(User user) {
    if (user.getName() == null || user.getName().isEmpty()) {
        throw new ValidationException("名前は必須です");
    }
}

ポイント:

  • 2回以上同じコードがあれば検討
  • ただし、たまたま同じだけで意味が違う場合は分けたまま

リファクタリングの進め方

1. 動作確認できる状態を維持

重要:
リファクタリング前と後で、動作が変わっていないことを確認する

方法:
- 自動テストがあれば実行
- なければ手動で動作確認

2. 小さく、少しずつ

❌ 悪い進め方
大規模な変更を一気に行う
→ どこで壊れたか分からない

✅ 良い進め方
小さな改善を1つずつ行う
→ 問題があればすぐに戻せる

3. コミットを細かく

# リファクタリングごとにコミット
git commit -m "変数名をより明確な名前に変更"
git commit -m "calculateTotalメソッドを抽出"
git commit -m "早期リターンでネストを削減"

1年目がリファクタリングで注意すべきこと

注意1: 他人のコードを大きく変えない

❌ やってはいけない
先輩が書いた100行のコードを
「読みにくいから」と勝手に書き換える

✅ やっていいこと
- 自分が書いたコードを改善
- レビューで指摘されたコードを修正
- 先輩に相談してから変更

注意2: 時間をかけすぎない

❌ 完璧を目指して何時間もかける
→ 本来のタスクが終わらない

✅ 基本的な改善にとどめる
→ 動くコード > 完璧なコード

注意3: 機能追加と混ぜない

❌ リファクタリングと機能追加を同時にやる
→ バグの原因が分からなくなる
→ レビューが大変

✅ 分けてコミット
1. リファクタリングだけをコミット
2. 機能追加を別コミット

リファクタリングのタイミング

やるべきタイミング

✅ コードレビュー前
→ 指摘を減らせる

✅ バグ修正のついで
→ 原因となった分かりにくいコードを改善

✅ 新機能追加の前
→ 追加しやすい構造に整える

避けるべきタイミング

❌ 締め切り直前
→ リスクが高い

❌ よく分からないコード
→ 意図を理解してから

❌ テストがないコード
→ 壊れても分からない

実践チェックリスト

リファクタリング時は、以下を確認:

基本

  • [ ] 動作が変わっていないことを確認した
  • [ ] 小さな単位で改善している
  • [ ] コミットを細かく分けている

改善内容

  • [ ] 意味のある名前に変えた
  • [ ] マジックナンバーを定数にした
  • [ ] 長いメソッドを分割した
  • [ ] 深いネストを減らした
  • [ ] 重複コードをまとめた

注意点

  • [ ] 他人のコードを勝手に大きく変えていない
  • [ ] 時間をかけすぎていない
  • [ ] 機能追加と混ぜていない

次のステップ

コードを整えたら、提出前の最終確認としてセルフチェックを行います。

Step7: セルフチェック


関連ページ