策略模式在项目中的运用

49 阅读1分钟

最近在写一个功能,是根据传递过来的参数执行不同的逻辑,为了后续代码可扩展性以及代码的耦合度降低,尽量不修改原有逻辑的基础上,使用了策略模式来解决问题,省去了大量的if else

例: 现在有前端给你传递一个action,并传递body,你要根据这个action去处理不同的业务逻辑,那么首先最懒的办法是想到if判断,但是后期如果有多个action,那么就像叠罗汉一样,代码越来越臃肿,可维护性极差,当然,如果这个action数量本来就很少,比如两三个,还是if更简单的

public String getStr(String action){
   if("123".equals(action)){
       return "123";
   }
   if("456".equals(action)){
       return "456";
   }
   if("789".equals(action)){
       return "789";
   }
   ...
   // 这样的话,后期每增加一个,你就得多往里边写一段代码
}

现在我们来用策略模式来解决

  1. 首先定义一个接口
public interface ActionStrategy{
    void doSth();
}
  1. 定义接口的实现类
@Component("action1")
@Slf4j
public class Impl1 implements ActionStrategy{
    @Override
    public void doSth(){
        log.info("执行impl1");
    }
}

@Component("action2")
@Slf4j
public class Impl2 implements ActionStrategy{
    @Override
    public void doSth(){
        log.info("执行impl2");
    }
}
  1. 定义上下文类,用于往出根据action取出不同的实现类
@Service
public class StrategyContext{
    private final Map<String, ActionStrategy> strategyMap = new ConcurrentHashMap<>();
    
    // 这里利用的是Spring的发现机制,将实现类put到map中
    public StrategyContext(Map<String, ActionStrategy> map){
        this.strategyMap.clear();
        map.forEach(this.strategyMap::put);
    }
    
    /**
     * 根据action来获取ActionStrategy接口的实现类对象
     */
    public ActionStrategy getActionStrategy(String action){
        return strategyMap.get(action);
    }
}
  1. 直接注入StrategyContext即可
    @AutoWired
    private StrategyContext strategyContext;
    
    
    public void doSth(String action){
        ActionStrategy actionStrategy = strategyContext.getActionStrategy(action);
        if(actionStrategy != null){
            actionStrategy.doSth();
        }
    }