策略模式-java实战

策略模式(Strategy Pattern)是一种行为型模式。它定义了一系列算法,并将每一个算法封装起来,使它们可以互换使用,算法的变化不会影响使用算法的用户。

使用场景

当一个系统中有许多类,它们之间的区别仅在于它们的行为时。

存在多种相似算法,使用条件语句(如if...else、switch...case)维护逻辑变化。

场景假设

存在一个功能页面,操作的功能需要按历史数据、实时数据、未来数据等时间条件实现。

此时,普通实现,就会存在大量的以下条件语句

  if(date == 历史){
    历史业务逻辑
  }
  if(date == 未来){
    未来业务逻辑
  }
  if(date == 实时){
    实时业务逻辑
  }

如果,后续业务出现新的时间条件,就需要一直往后面叠加if条件,就会变的越来越长,慢慢就形成业内所说的屎山。

实现步骤

  • 定义策略接口:所有策略类都将实现这个统一的接口。

  • 实现具体策略类:每个策略类封装一个具体的算法或行为。

  • 实现环境类:包含一个策略对象的引用,并通过该引用调用策略。

代码示例

  • 定义通用返回vo

      public class BaseVo {
      
      }
    
  • 定义策略接口:

        import com.example.service.strategy.vo.BaseVo;
    
        import java.util.List;
    
        public interface Strategy {
    
            List<Object> queryList();
    
        }
    
  • 定义具体返回对象

      public class FutureVo extends BaseVo{
      }
      
      public class HisVo extends BaseVo{
      }
    
      public class RealtimeVo extends BaseVo{
      }
    
  • 定义具体策略

    
      //策略枚举
    
      import com.example.service.strategy.Future;
      import com.example.service.strategy.History;
      import com.example.service.strategy.Realtime;
      import com.example.service.strategy.Strategy;
    
      public enum Type {
    
          HIS("0", new History()),
          TIME("1",new Realtime()),
          FUTURE("2",new Future())
          ;
    
          private final String key;
    
          private final Strategy strategy;
    
          Type(String s, Strategy strategy) {
              this.key= s;
              this.strategy= strategy;
          }
    
          public String getKey() {
              return key;
          }
    
          public Strategy getStrategy() {
              return strategy;
          }
      }
      
      // his
    
      import com.example.service.strategy.vo.BaseVo;
      import com.example.service.strategy.vo.HisVo;
    
      import java.util.Collections;
      import java.util.List;
    
      public class History implements Strategy {
    
          @Override
          public List<Object> queryList() {
              System.out.println("History");
              return Collections.singletonList(new HisVo());
          }
      }
    
      //future
    
      import com.example.service.strategy.vo.BaseVo;
      import com.example.service.strategy.vo.FutureVo;
    
      import java.util.Collections;
      import java.util.List;
    
      public class Future implements Strategy {
    
          @Override
          public List<Object> queryList(){
              System.out.println("Future");
              return Collections.singletonList(new FutureVo());
          }
      }
      
      //real time
    
      import com.example.service.strategy.vo.BaseVo;
      import com.example.service.strategy.vo.RealtimeVo;
    
      import java.util.Collections;
      import java.util.List;
    
      public class Realtime implements Strategy {
    
          @Override
          public List<Object> queryList() {
              RealtimeVo realtimeVo = new RealtimeVo();
              System.out.println("Realtime");
              return Collections.singletonList(realtimeVo);
          }
    
      }
      
    
  • 定义策略工具类

        import com.example.service.strategy.enums.Type;
        import com.example.service.strategy.vo.BaseVo;
        import org.springframework.stereotype.Service;
    
        import java.util.List;
    
        @Service
        public class ClientContext {
    
            public List<Object> query(Type type){
              return getStrategy(type).queryList();
            }
    
            public Strategy getStrategy(Type type){
                return type.getStrategy();
            }
        }
      
    
  • 测试类

      import com.example.service.strategy.enums.Type;
    
      public class Test {
    
          public static void main(String[] args){
            ClientContext contextClient = new ClientContext();
            List<Object> hisVoList= contextClient.query(Type.HIS);
            List<Object> timeVoList=contextClient.query(Type.TIME);
            List<Object> futureVos= contextClient.query(Type.FUTURE);
          }
    
      }
    
    
  • 结果

      History
      Realtime
      Future
    
    

将策略交给spring容器管理的实现方式

差异主要是在工具类/环境类的实现,即策略的获取。

  • 定义策略接口

      import com.example.service.strategy.vo.BaseVo;
    
      import java.util.List;
    
      public interface Strategy {
    
          String getKey();
    
          List<Object> queryList();
    
      }
      
    
  • 定义策略具体类

      // 策略枚举类
    
      public enum StrategyType {
    
          HIS("0"),
          TIME("1"),
          FUTURE("2")
          ;
    
          private final String key;
    
    
          StrategyType(String s) {
              this.key= s;
          }
    
          public String getKey() {
              return key;
          }
    
      }
    
      //策略类
      
      //his
    
      import com.example.service.strategy.enums.StrategyType;
      import com.example.service.strategy.vo.BaseVo;
      import com.example.service.strategy.vo.HisVo;
    
      import java.util.Collections;
      import java.util.List;
    
      public class History implements Strategy {
    
          @Override
          public String getKey() {
              return StrategyType.HIS.getKey();
          }
    
          @Override
          public List<Object> queryList() {
              System.out.println("History");
              return Collections.singletonList(new HisVo());
          }
      }
    
      //future
    
      import com.example.service.strategy.enums.StrategyType;
      import com.example.service.strategy.vo.BaseVo;
      import com.example.service.strategy.vo.FutureVo;
    
      import java.util.Collections;
      import java.util.List;
    
      public class Future implements Strategy {
    
          @Override
          public String getKey() {
              return StrategyType.FUTURE.getKey();
          }
    
          @Override
          public List<Object> queryList(){
              System.out.println("Future");
              return Collections.singletonList(new FutureVo());
          }
      }
    
      //real time
    
      import com.example.service.strategy.enums.StrategyType;
      import com.example.service.strategy.vo.BaseVo;
      import com.example.service.strategy.vo.RealtimeVo;
    
      import java.util.Collections;
      import java.util.List;
    
      public class Realtime implements Strategy {
    
          @Override
          public String getKey() {
              return StrategyType.TIME.getKey();
          }
    
          @Override
          public List<Object> queryList() {
              RealtimeVo realtimeVo = new RealtimeVo();
              System.out.println("Realtime");
              return Collections.singletonList(realtimeVo);
          }
    
      }
      
    
  • 定义策略上下文类

      import com.example.service.strategy.enums.StrategyType;
      import com.example.service.strategy.vo.BaseVo;
      import org.springframework.beans.BeansException;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.ApplicationContextAware;
      import org.springframework.stereotype.Component;
    
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
    
      @Component
      public class SpringClientContext implements ApplicationContextAware {
    
          private final Map<String,Strategy> strategyMap = new HashMap<>();
    
          public List<Object> query(StrategyType strategyType){
              return getStrategy(strategyType).queryList();
          }
    
          public Strategy getStrategy(StrategyType strategyType){
              return strategyMap.get(strategyType.getKey());
          }
    
    
          @Override
          public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
              Map<String,Strategy> tmpMap = applicationContext.getBeansOfType(Strategy.class);
              tmpMap.values().forEach(strategy -> strategyMap.put(strategy.getKey(),strategy));
          }
      }
    

springboot 自动注入策略类

   /**
   * Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类
   */
  @Resource
  private Map<String, Strategy> StrategyMap;

  @Resource
  private List<Strategy> StrategyList;

posted @ 2024-12-09 18:38  抒写  阅读(16)  评论(0编辑  收藏  举报