使用策略模式优化大量if...else代码

一. 场景

假如我们有一个订单业务,根据会员的类型不同,使用if...else判断,然后去执行不同的业务操作,伪代码如下:

public class OrderService {

  public void method(HttpServletRequest req) {
    //type:会员类型
    String type = req.getParameter("type");
    if("free".equals(type)) {
      System.out.println("免费用户业务开始。。。");
    } else if("normal".equals(type)) {
      System.out.println("普通会员业务开始。。。");
    } else if("high".equals(type)) {
      System.out.println("高级会员业务开始。。。");
    } else if("super".equals(type)) {
      System.out.println("超级会员业务开始。。。");
    } else {
      throw new Exception("类型错误.");
    }
  }
}

根据会员的类型type,在if...else判断是免费用户、普通会员、高级会员、超级会员,执行对应的业务操作。

实际业务可能会更多,叠加很多的if...else,代码看起来很臃肿,不容易维护

二. 优化

策略模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。

设计模式里的策略模式,可以用来优化if...elseswitch...case多重条件语句的代码

  1. 抽象业务处理器

    public abstract class AbstractHandler {
      public abstract void handle();
      public abstract String type();
    }
    
  2. 把业务处理器和处理的类型放到一个容器里

    @Component
    public class AbstractHandlerProcessor implements ApplicationContextAware {
      
      private ApplicationContext context;
      
      private Map<String, AbstractHandler> processorMap = new HashMap<>();
      
      public AbstractHandler choose(String type) {
        AbstractHandler handler = map.get(type);
        if(null == handler) {
          throw new Exception("不支持的type类型,联系管理员。。。")
        }
        return handler;
      }
      
      @PostConstruct
      public void register() {
        Map<String, AbstractHandler> handlerMap = context.getBeansOfType(AbstractHandler.class);
        for(AbstractHandler handler : handlerMap.values()) {
          processorMap.put(handler.type(),handler);
        }
      }
      
      @Override
      public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context=applicationContext;
      }
    }
    

    PostConstruct注解会在应用启动时候,加载所有AbstractHandler类型的处理器,放到AbstractHandlerProcessormap容器中。注意加@Component注解

  3. 编写响应的处理器

    /**
     * 免费用户
     */
    @Component
    public class FreeHandler extends AbstractHandler {
      
        @Override
        public void handle() {
            System.out.println("免费用户业务开始。。。");
        }
    
        @Override
        public String type() {
            return "free";
        }
    }
    
    /**
     * 普通会员
     */
    @Component
    public class NormalHandler extends AbstractHandler {
      
        @Override
        public void handle() {
            System.out.println("普通会员业务开始。。。");
        }
    
        @Override
        public String type() {
            return "normal";
        }
    }
    
    /**
     * 高级会员
     */
    @Component
    public class HighHandler extends AbstractHandler {
      
        @Override
        public void handle() {
            System.out.println("高级会员业务开始。。。");
        }
    
        @Override
        public String type() {
            return "high";
        }
    }
    
    /**
     * 超级会员
     */
    @Component
    public class SuperHandler extends AbstractHandler {
      
        @Override
        public void handle() {
            System.out.println("超级会员业务开始。。。");
        }
    
        @Override
        public String type() {
            return "super";
        }
    }
    
  4. 测试

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes=Application.class)// 指定spring-boot的启动类
    public class HandlerTest {
    
        @Autowired
        private AbstractHandlerProcessor chooser;
    
        @Test
        public void test() throws Exception{
            //准备数据
            String type = "free";
            //获取任务类型对应的solver
            AbstractHandlerProcessor processor = chooser.choose(type);
            //调用不同handle的方法进行处理
            processor.handle();
        }
    }
    
三. 总结

优点

  1. 多重条件语句不易维护,而使用策略模式可以避免使用多重条件语句,如if...else 语句、switch...case语句。
  2. 符合面向对象的开闭原则,在不修改原来代码的情况下,可以很好的扩展
  3. 算法的使用放到环境类,算法的实现放到具体的策略类,实现了二者的分离

缺点

  1. 客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类
  2. 策略模式造成很多的策略类,增加维护难度
  3. 增加了学习成本和维护成本
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值