Java | フォールスルーのある switch を戦略パターンで安全に置き換える練習問題集

Java Java
スポンサーリンク

では、先ほどの フォールスルーを戦略パターンで安全に置き換えた解答例 を、コード+UML図付き で順に示します。


解答例1:管理者・ユーザーの共通処理

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

// 2. 共通ユーザー処理
class UserTask implements UserStrategy {
    public void execute() {
        System.out.println("共通ユーザー処理");
    }
}

// 3. 管理者専用処理(共通処理を内部で呼び出す)
class AdminUserTask implements UserStrategy {
    private final UserStrategy userTask = new UserTask();

    public void execute() {
        System.out.println("管理者専用処理");
        userTask.execute(); // 共通処理呼び出し(フォールスルーを安全に再現)
    }
}

// 4. ゲスト処理
class GuestUserTask implements UserStrategy {
    public void execute() {
        System.out.println("ゲスト処理");
    }
}

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

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

UML図(ASCII版)

           +----------------+
           | UserStrategy   | <<interface>>
           +----------------+
           | + execute()    |
           +----------------+
                   ^
                   |
   ------------------------------
   |             |              |
+----------+  +---------+    +---------+
| AdminUser|  | UserTask|    | GuestUser|
+----------+  +---------+    +---------+
| +execute()| | +execute()|  | +execute()|
+----------+  +---------+    +---------+

解答例2:ステップ実行バッチ

interface StepStrategy {
    void execute();
}

class Step1 implements StepStrategy {
    public void execute() {
        System.out.println("Step1実行");
    }
}

class Step2 implements StepStrategy {
    public void execute() {
        System.out.println("Step2実行");
    }
}

class Step3 implements StepStrategy {
    public void execute() {
        System.out.println("Step3実行");
    }
}

class Step4 implements StepStrategy {
    public void execute() {
        System.out.println("Step4実行");
    }
}

// ファクトリ
class StepFactory {
    static StepStrategy[] getStrategiesFrom(int step) {
        switch (step) {
            case 1: return new StepStrategy[]{new Step1(), new Step2(), new Step3(), new Step4()};
            case 2: return new StepStrategy[]{new Step2(), new Step3(), new Step4()};
            case 3: return new StepStrategy[]{new Step3(), new Step4()};
            case 4: return new StepStrategy[]{new Step4()};
            default: throw new IllegalArgumentException("不正なステップ");
        }
    }
}

// メイン
public class Main2 {
    public static void main(String[] args) {
        int step = 2;
        StepStrategy[] steps = StepFactory.getStrategiesFrom(step);
        for (StepStrategy s : steps) {
            s.execute();
        }
    }
}
Java

UML図(ASCII版)

          +----------------+
          | StepStrategy   | <<interface>>
          +----------------+
          | + execute()    |
          +----------------+
                 ^
   ------------------------------------
   |          |           |           |
+------+   +------+   +------+   +------+
| Step1 |  | Step2 |  | Step3 |  | Step4 |
+------+   +------+   +------+   +------+
| +exec |  | +exec |  | +exec |  | +exec |
+------+   +------+   +------+   +------+
                 ^
                 |
           +---------------+
           | StepFactory   |
           +---------------+
           | +getStrategies|
           +---------------+

解答例3:権限累積処理(ADMIN → MODERATOR → USER → GUEST)

interface RoleStrategy {
    void execute();
}

class GuestRole implements RoleStrategy {
    public void execute() { System.out.println("GUEST処理"); }
}

class UserRole implements RoleStrategy {
    private final RoleStrategy next = new GuestRole();
    public void execute() {
        System.out.println("USER処理");
        next.execute(); // 下位権限を順に実行
    }
}

class ModeratorRole implements RoleStrategy {
    private final RoleStrategy next = new UserRole();
    public void execute() {
        System.out.println("MODERATOR処理");
        next.execute();
    }
}

class AdminRole implements RoleStrategy {
    private final RoleStrategy next = new ModeratorRole();
    public void execute() {
        System.out.println("ADMIN処理");
        next.execute();
    }
}

// ファクトリ
class RoleFactory {
    static RoleStrategy getStrategy(String role) {
        switch (role) {
            case "ADMIN": return new AdminRole();
            case "MODERATOR": return new ModeratorRole();
            case "USER": return new UserRole();
            case "GUEST": return new GuestRole();
            default: throw new IllegalArgumentException("不明な権限");
        }
    }
}

// メイン
public class Main3 {
    public static void main(String[] args) {
        String role = "MODERATOR";
        RoleStrategy strategy = RoleFactory.getStrategy(role);
        strategy.execute();
    }
}
Java

UML図(ASCII版)

           +----------------+
           | RoleStrategy   | <<interface>>
           +----------------+
           | +execute()     |
           +----------------+
                   ^
                   |
   --------------------------------------
   |              |           |         |
+---------+ +---------+ +--------+ +---------+
| Admin   | | Moderator| | User  | | Guest   |
+---------+ +---------+ +--------+ +---------+
| +exec() | | +exec() | | +exec()| | +exec()|
+---------+ +---------+ +--------+ +---------+
(Admin, Moderator, Userは下位権限を内部呼び出し)

解説ポイント(共通)

  1. フォールスルーを安全に再現
    • 下位処理をオブジェクト内で呼び出すことで明示的に制御
  2. mainコードがシンプル
    • strategy.execute() だけで処理完結
  3. 拡張性
    • 新しい権限やステップを追加する場合、クラスとファクトリに追加するだけ
  4. テストしやすい
    • 個別の戦略クラスを単体テスト可能

💡 この練習問題集と解答例をマスターすれば、

  • 意図的フォールスルーや複雑 switch の危険を理解
  • 戦略パターンで安全・可読性高く置き換えるスキル
  • 共通処理・累積処理の整理方法

まで一気に身につきます。

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