Java | 「switch → 戦略パターン」リファクタ練習問題

Java Java
スポンサーリンク

では、先ほどの 3問セット戦略パターンで実装した解答例 を順に示します。


解答例1:ユーザー権限ごとの処理

// 1. インターフェース
interface UserStrategy {
    void execute();
}

// 2. 各ユーザーごとのクラス
class AdminUser implements UserStrategy {
    public void execute() {
        logAccess();
        showAdminMenu();
    }
    private void logAccess() { System.out.println("アクセスログ記録"); }
    private void showAdminMenu() { System.out.println("管理者メニュー表示"); }
}

class NormalUser implements UserStrategy {
    public void execute() {
        showUserMenu();
    }
    private void showUserMenu() { System.out.println("ユーザーメニュー表示"); }
}

class GuestUser implements UserStrategy {
    public void execute() {
        showGuestMenu();
    }
    private void showGuestMenu() { System.out.println("ゲストメニュー表示"); }
}

// 3. ファクトリ
class UserFactory {
    static UserStrategy getStrategy(String userType) {
        switch (userType) {
            case "ADMIN": return new AdminUser();
            case "USER": return new NormalUser();
            case "GUEST": return new GuestUser();
            default: throw new IllegalArgumentException("不明なユーザー種別");
        }
    }
}

// 4. メイン
public class Main1 {
    public static void main(String[] args) {
        String userType = "ADMIN";
        UserStrategy strategy = UserFactory.getStrategy(userType);
        strategy.execute();
    }
}
Java

解答例2:交通信号(TrafficLight)

// 1. インターフェース
interface TrafficLightStrategy {
    void execute();
}

// 2. 各信号色クラス
class RedLight implements TrafficLightStrategy {
    public void execute() {
        System.out.println("止まれ");
    }
}

class YellowLight implements TrafficLightStrategy {
    public void execute() {
        System.out.println("注意");
    }
}

class GreenLight implements TrafficLightStrategy {
    public void execute() {
        System.out.println("進め");
    }
}

// 3. ファクトリ
class TrafficLightFactory {
    static TrafficLightStrategy getStrategy(String light) {
        switch (light) {
            case "RED": return new RedLight();
            case "YELLOW": return new YellowLight();
            case "GREEN": return new GreenLight();
            default: throw new IllegalArgumentException("不明な信号");
        }
    }
}

// 4. メイン
public class Main2 {
    public static void main(String[] args) {
        String light = "YELLOW";
        TrafficLightStrategy strategy = TrafficLightFactory.getStrategy(light);
        strategy.execute();
    }
}
Java

解答例3:ポイント計算(ShopPoints)

// 1. インターフェース
interface PointStrategy {
    double calculate(double purchase);
}

// 2. 各ランクのクラス
class GoldPoint implements PointStrategy {
    public double calculate(double purchase) { return purchase * 0.05; }
}

class SilverPoint implements PointStrategy {
    public double calculate(double purchase) { return purchase * 0.03; }
}

class BronzePoint implements PointStrategy {
    public double calculate(double purchase) { return purchase * 0.01; }
}

// 3. ファクトリ
class PointFactory {
    static PointStrategy getStrategy(String rank) {
        switch (rank) {
            case "GOLD": return new GoldPoint();
            case "SILVER": return new SilverPoint();
            case "BRONZE": return new BronzePoint();
            default: throw new IllegalArgumentException("不明なランク");
        }
    }
}

// 4. メイン
public class Main3 {
    public static void main(String[] args) {
        String rank = "SILVER";
        double purchase = 1000;

        PointStrategy strategy = PointFactory.getStrategy(rank);
        double point = strategy.calculate(purchase);
        System.out.println("加算ポイント:" + point);
    }
}
Java

解説ポイント

  1. 各条件ごとにクラス化
    • ADMIN, USER, GUEST など条件ごとの処理を1クラスにまとめる
  2. インターフェースで共通化
    • メソッド名は統一 (execute()calculate() など)
  3. ファクトリで選択
    • switch 文はファクトリ内部だけに残すか、Mapを使って置き換え可能
  4. メインコードは switch 不要
    • 処理対象のオブジェクトを取得して strategy.execute() または strategy.calculate() を呼ぶだけ
  5. 拡張性
    • 新しいユーザータイプやランクを追加するときは、クラスを追加するだけで済む

💡 この方法を使えば、意図的フォールスルーや複雑な switch が不要になり、可読性・拡張性が大幅に向上します。

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