策略模式定義一系列算法,封裝每一個,使它們可互換。本文以「四則運算」為例,展示如何將加減乘除封裝為獨立策略類,Context 運行時注入具體策略,徹底替代 if-else 鏈,實現開閉原則與單一職責。
// 抽象策略
interface Strategy {
void doOperation(int num1, int num2);
}
// 具體策略
class StrategyAdd implements Strategy {
public void doOperation(int n1, int n2) {
System.out.println("執行加法:" + n1 + "+" + n2 + "=" + (n1+n2));
}
}
class StrategySub implements Strategy { /* 減法 */ }
class StrategyMul implements Strategy { /* 乘法 */ }
class StrategyDiv implements Strategy { /* 除法 */ }
// 環境角色
class Context {
private Strategy strategy;
public Context(Strategy strategy) { this.strategy = strategy; }
public void execute(int n1, int n2) { strategy.doOperation(n1, n2); }
}
// 客戶端:運行時動態切換
public class Demo {
public static void main(String[] args) {
Context ctx = new Context(new StrategyAdd());
ctx.execute(10, 5); // 加法
ctx = new Context(new StrategyDiv());
ctx.execute(10, 5); // 除法
}
}
實際開發中,常根據參數類型選擇策略。傳統寫法:
if (type == 1) return new StrategyA();
else if (type == 2) return new StrategyB();
// ...
策略模式重構:
// 策略工廠/註冊表
@Component
public class StrategyFactory {
private final Map<Integer, Strategy> map = new HashMap<>();
@PostConstruct
public void init() {
map.put(1, new StrategyA());
map.put(2, new StrategyB());
// 支援 Spring 自動掃描註冊:@Component 掃描所有 Strategy 實現類
}
public Strategy getStrategy(int type) {
return map.getOrDefault(type, new DefaultStrategy());
}
}
// 業務代碼極度簡潔
public Result process(Request req) {
Strategy strategy = factory.getStrategy(req.getType());
return strategy.execute(req);
}
if-else 分散至各策略類與工廠註冊HttpServlet.service():根據 HTTP 方法分派 doGet/doPost 等策略策略模式不僅是「替換 if-else」,更是將業務變化點識別、封裝、標準化的架構思維。