では「練習問題3:ログレベルの出力」を switch文 → 戦略パターン にリファクタリングしてみましょう。
元のコード(switch文)
switch (logLevel) {
case "INFO":
System.out.println("[INFO] 通常ログ");
break;
case "WARN":
System.out.println("[WARN] 注意ログ");
break;
case "ERROR":
System.out.println("[ERROR] エラーログ");
break;
default:
System.out.println("[DEBUG] デバッグログ");
}
Java戦略パターンでのリファクタ解答
1. 戦略インターフェース
interface LogStrategy {
void log(String message);
}
Java2. 具体的な戦略クラス
class InfoLog implements LogStrategy {
public void log(String message) {
System.out.println("[INFO] " + message);
}
}
class WarnLog implements LogStrategy {
public void log(String message) {
System.out.println("[WARN] " + message);
}
}
class ErrorLog implements LogStrategy {
public void log(String message) {
System.out.println("[ERROR] " + message);
}
}
class DebugLog implements LogStrategy {
public void log(String message) {
System.out.println("[DEBUG] " + message);
}
}
Java3. コンテキスト(戦略選択)
import java.util.HashMap;
import java.util.Map;
class LogContext {
private static final Map<String, LogStrategy> strategies = new HashMap<>();
static {
strategies.put("INFO", new InfoLog());
strategies.put("WARN", new WarnLog());
strategies.put("ERROR", new ErrorLog());
strategies.put("DEBUG", new DebugLog()); // default用
}
public static void execute(String level, String message) {
LogStrategy strategy = strategies.getOrDefault(level, new DebugLog());
strategy.log(message);
}
}
Java4. 利用側
public class Main {
public static void main(String[] args) {
LogContext.execute("INFO", "通常ログ");
LogContext.execute("WARN", "注意ログ");
LogContext.execute("ERROR", "エラーログ");
LogContext.execute("UNKNOWN", "未知のログ"); // デフォルトでDEBUG扱い
}
}
Java解説
- switch文の問題点
- ログレベルが増えるとcaseが増えて肥大化。
- defaultの扱いが曖昧になりがち。
- 戦略パターンのメリット
- ログレベルごとにクラスを分けるので責務が明確。
- 新しいログレベル(例:TRACE、FATAL)を追加する場合はクラスとMap登録だけで済む。
getOrDefaultを使うことで「未知のログレベルはDEBUG扱い」といった柔軟な制御が可能。


