一、简介
1、定义
策略模式(Strategy Pattern)是一种行为设计模式,它定义一系列算法,将每一个算法封装起来,算法之间可以相互替换。通过定义策略接口和具体策略实现类,将算法封装为对象,并在运行时选择对应的算法。
2、策略模式的结构
策略模式涉及以下几个角色:
策略(Strategy)接口:提供所有的具体策略类所需的接口。
具体策略(ConcreteStrategy)实现:实现策略接口,包装了相关的算法。
环境(Context):维护策略,调用对应的策略。
二、Java实现案例
1、策略模式通用案例
/**
* @Description: 策略接口
* @Date: 2025-02-08 13:16
* @Author: gaoyufei
**/
public interface Strategy {
void execute();
}
/**
* @Description: 具体策略A
* @Date: 2025-02-08 13:17
* @Author: gaoyufei
**/
public class ConcreteStrategyA implements Strategy{
@Override
public void execute() {
System.out.println("执行具体策略A");
}
}
/**
* @Description: 具体策略B
* @Date: 2025-02-08 13:17
* @Author: gaoyufei
**/
public class ConcreteStrategyB implements Strategy{
@Override
public void execute() {
System.out.println("执行具体策略B");
}
}
/**
* @Description: 上下文类
* @Date: 2025-02-08 13:18
* @Author: gaoyufei
**/
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy=strategy;
}
public void setStrategy(Strategy strategy){
this.strategy=strategy;
}
public void executeStrategy(){
strategy.execute();
}
}
/**
* @Description: 客户端
* @Date: 2025-02-08 13:20
* @Author: gaoyufei
**/
public class ClientMain {
public static void main(String[] args) {
Context context=new Context(new ConcreteStrategyA());
context.executeStrategy();
context.setStrategy(new ConcreteStrategyB());
context.executeStrategy();
}
}
2、加减乘除运算策略案例
/**
* @Description: 运算接口
* @Date: 2025-02-08 13:32
* @Author: gaoyufei
**/
public interface Operation {
int execute(int a, int b);
}
/**
* @Description: 加法运算
* @Date: 2025-02-08 13:33
* @Author: gaoyufei
**/
public class AddOperation implements Operation{
@Override
public int execute(int a, int b) {
return a+b;
}
}
/**
* @Description: 减法运算
* @Date: 2025-02-08 13:33
* @Author: gaoyufei
**/
public class SubOperation implements Operation{
@Override
public int execute(int a, int b) {
return a-b;
}
}
/**
* @Description: 乘法运算
* @Date: 2025-02-08 13:34
* @Author: gaoyufei
**/
public class MultiOperation implements Operation{
@Override
public int execute(int a, int b) {
return a*b;
}
}
/**
* @Description: 除法运算
* @Date: 2025-02-08 13:34
* @Author: gaoyufei
**/
public class DivOperation implements Operation{
@Override
public int execute(int a, int b) {
return a/b;
}
}
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* @Description: 操作者工厂类
* @Date: 2025-02-08 13:35
* @Author: gaoyufei
**/
public class OperatorFactory {
private static Map<String, Operation> map=new HashMap<>();
static {
map.put("+",new AddOperation());
map.put("-",new SubOperation());
map.put("*",new MultiOperation());
map.put("/",new DivOperation());
}
public static Optional<Operation> getOperation(String operator){
return Optional.ofNullable(map.get(operator));
}
}
/**
* @Description: 测试类
* @Date: 2025-02-08 13:39
* @Author: gaoyufei
**/
public class OperatorTestMain {
public static void main(String[] args) {
Operation add = OperatorFactory.getOperation("+").orElseThrow(() -> new IllegalArgumentException("无效操作"));
int addRes = add.execute(2, 3);
System.out.println("2+3="+addRes);
Operation sub = OperatorFactory.getOperation("-").orElseThrow(() -> new IllegalArgumentException("无效操作"));
int subRes = sub.execute(5, 1);
System.out.println("5-1="+subRes);
Operation multi = OperatorFactory.getOperation("*").orElseThrow(() -> new IllegalArgumentException("无效操作"));
int multiRes = multi.execute(2, 2);
System.out.println("2*2="+multiRes);
Operation div = OperatorFactory.getOperation("/").orElseThrow(() -> new IllegalArgumentException("无效操作"));
int divRes = div.execute(6, 2);
System.out.println("6/2="+divRes);
}
}
3、springboot项目策略模式实现
/**
* @Description: Strategy
* @Date: 2025-02-08 14:40
* @Author: gaoyufei
**/
public interface Strategy {
void method();
}
import org.springframework.stereotype.Service;
/**
* @Description: 策略A
* @Date: 2025-02-08 14:40
* @Author: gaoyufei
**/
@Service("strategyA")
public class StrategyA implements Strategy{
@Override
public void method() {
System.out.println("实现策略A方法");
}
}
import org.springframework.stereotype.Service;
/**
* @Description: 策略B
* @Date: 2025-02-08 14:40
* @Author: gaoyufei
**/
@Service("strategyB")
public class StrategyB implements Strategy{
@Override
public void method() {
System.out.println("实现策略B方法");
}
}
import org.springframework.stereotype.Service;
/**
* @Description: 策略C
* @Date: 2025-02-08 14:40
* @Author: gaoyufei
**/
@Service("strategyC")
public class StrategyC implements Strategy{
@Override
public void method() {
System.out.println("实现策略C方法");
}
}
/**
* @Description: 策略枚举
* @Date: 2025-02-08 14:43
* @Author: gaoyufei
**/
public enum StrategyEnum {
strategyA(1,"strategyA"),
strategyB(2,"strategyB"),
strategyC(3,"strategyC");
private Integer code;
private String name;
public Integer getCode() {
return code;
}
public String getName() {
return name;
}
StrategyEnum(Integer code, String name){
this.code=code;
this.name=name;
}
public static String getName(Integer code){
StrategyEnum[] enums = StrategyEnum.values();
for(int i=0;i<enums.length;i++){
if(enums[i].getCode().equals(code)){
return enums[i].getName();
}
}
return null;
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
/**
* @Description: StrategyContext
* @Date: 2025-02-08 14:50
* @Author: gaoyufei
**/
@Component
public class StrategyContext {
private static Map<String,Strategy> strategyMap=new HashMap<>();
@Autowired
private ApplicationContext applicationContext;
@PostConstruct
public void init(){
strategyMap.putAll(applicationContext.getBeansOfType(Strategy.class));
}
public Strategy getStrategy(Integer code){
return strategyMap.get(StrategyEnum.getName(code));
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description: StrategyController
* @Date: 2025-02-08 14:57
* @Author: gaoyufei
**/
@RestController
public class StrategyController {
@Autowired
private StrategyContext strategyContext;
@RequestMapping("/method")
public void testMethod(@RequestParam("code") Integer code){
Strategy strategy = strategyContext.getStrategy(code);
if(strategy!=null) {
strategy.method();
}
}
}