Java | フォールスルーを使わないで同じ挙動を実現するリファクタ例(戦略パターンなど)

Java Java
スポンサーリンク

「フォールスルーを使って複数条件をまとめる」代わりに、戦略パターン(Strategy Pattern)などの設計パターンを使うと、より柔軟で保守性の高いコードになります。


戦略パターンでのリファクタ例

元のコード(フォールスルーあり)

switch (status) {
    case "NEW":
    case "PENDING":
        handleNewOrPending();
        break;
    case "APPROVED":
        handleApproved();
        break;
    case "REJECTED":
        handleRejected();
        break;
    default:
        throw new IllegalStateException("未知のステータス: " + status);
}
Java

👉 「NEW」と「PENDING」をまとめるためにフォールスルーを使っている。


戦略パターンで書き換え

// 1. 戦略インターフェース
interface StatusHandler {
    void handle();
}

// 2. 具体的な戦略クラス
class NewOrPendingHandler implements StatusHandler {
    public void handle() {
        System.out.println("新規または保留状態の処理");
    }
}

class ApprovedHandler implements StatusHandler {
    public void handle() {
        System.out.println("承認済みの処理");
    }
}

class RejectedHandler implements StatusHandler {
    public void handle() {
        System.out.println("却下の処理");
    }
}

// 3. 戦略を選択するコンテキスト
class StatusContext {
    private static final Map<String, StatusHandler> handlers = new HashMap<>();
    static {
        handlers.put("NEW", new NewOrPendingHandler());
        handlers.put("PENDING", new NewOrPendingHandler());
        handlers.put("APPROVED", new ApprovedHandler());
        handlers.put("REJECTED", new RejectedHandler());
    }

    public static void execute(String status) {
        StatusHandler handler = handlers.get(status);
        if (handler != null) {
            handler.handle();
        } else {
            throw new IllegalStateException("未知のステータス: " + status);
        }
    }
}
Java

利用側

public class Main {
    public static void main(String[] args) {
        StatusContext.execute("NEW");      // 新規または保留状態の処理
        StatusContext.execute("APPROVED"); // 承認済みの処理
    }
}
Java

メリット

  • フォールスルー不要 → caseを並べる代わりに、同じ戦略クラスを複数キーに割り当てる。
  • 拡張性が高い → 新しいステータスが増えても、handlers.put("X", new XHandler())を追加するだけ。
  • テストしやすい → 各戦略クラスを単体テスト可能。
  • 責務分離 → switch文が肥大化せず、処理ごとにクラスが分かれる。

他のリファクタ手法

  • enum+メソッド
enum Status {
    NEW, PENDING, APPROVED, REJECTED;

    void handle() {
        switch (this) {
            case NEW:
            case PENDING:
                System.out.println("新規または保留状態");
                break;
            case APPROVED:
                System.out.println("承認済み");
                break;
            case REJECTED:
                System.out.println("却下");
                break;
        }
    }
}
Java

👉 enumに処理を持たせることで、switchを呼び出し側から隠蔽できる。

  • Map+ラムダ式(Java 8以降)
Map<String, Runnable> handlers = new HashMap<>();
handlers.put("NEW", () -> System.out.println("新規または保留"));
handlers.put("PENDING", () -> System.out.println("新規または保留"));
handlers.put("APPROVED", () -> System.out.println("承認済み"));
handlers.put("REJECTED", () -> System.out.println("却下"));

handlers.getOrDefault(status, () -> {
    throw new IllegalStateException("未知のステータス: " + status);
}).run();
Java

👉 シンプルに書けて、フォールスルー不要。


まとめ

  • フォールスルーを使わない方法としては
    • 戦略パターン(Strategy Pattern)
    • enumに処理を持たせる
    • Map+ラムダ式
  • どれも「複数条件をまとめたい」ケースで有効。
  • 実務では「戦略パターン」や「Map+ラムダ」が特に使いやすく、保守性が高い。

Java
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました