美文网首页Spring设计模式
Spring中如何实现策略模式

Spring中如何实现策略模式

作者: AbstractCulture | 来源:发表于2020-09-29 03:22 被阅读0次

    if-else

    假设现在要开发一个邮件服务,要对接所有的邮件服务提供厂商,那么代码可能是这样的:

    public class MailHandle {
        public void send(String providerName, String msg) {
            // 如果要发到 qq邮箱
            if ("qq".equals(providerName)) {
                sendMsgToQQ(msg);
            }
            // 如果要发到网易邮箱 
            else if ("ntes".equals(providerName)) {
                sendMsgToNtes(msg);
            }
            // 如果要发到阿里云邮箱
            else if ("alibaba".equals(providerName)) {
                sendMsgToAlibaba(msg);
            }
        }
    }
    

    Oh,My God!这简直是灾难,让我们用策略模式让代码更加具备扩展性吧。

    设计思想

    image.png

    Context: 对策略进行封装,对外暴露统一的方法send()。
    Strategy: 策略接口,定义抽象方法。
    implStrategy: 图中的QQ,NTES,Alibaba都是Strategy的实现类。实现具体的业务方法。

    代码实现

    • MailStrategyService
    public interface MailStrategyService {
    
        /**
         * 服务提供商名称
         *
         * @return
         */
        public String getServiceProviderName();
    
        /**
         * 发送邮件
         *
         * @param message
         */
        public void send(String message);
    
    }
    
    • NASDAQMailStrategyServiceImpl
    @Service
    @Slf4j
    public class NASDAQMailStrategyServiceImpl implements MailStrategyService {
    
        @Override
        public String getServiceProviderName() {
            return "ntes";
        }
    
        @Override
        public void send(String message) {
            log.info("现在向网易邮箱发送邮件:{}",message);
        }
    }
    
    • QQMailStrategyServiceImpl
    @Service
    @Slf4j
    public class QQMailStrategyServiceImpl implements MailStrategyService {
    
        @Override
        public String getServiceProviderName() {
            return "qq";
        }
    
        @Override
        public void send(String message) {
           log.info("向QQ邮箱发送邮件:{}",message);
        }
    }
    
    • MailStrategyContext
    @Component
    @Slf4j
    @Getter
    public class MailStrategyContext {
    
        /**
         * 策略
         * KEY为业务编码
         * VALUE为具体实现类
         */
        private final ConcurrentHashMap<String, MailStrategyService> strategy = new ConcurrentHashMap<>();
    
        /**
         * 注入所有实现 MailStrategyService 接口的类
         * 这里使用的是构造注入的方式将Bean注入进来
         *
         * @param mailServiceList
         */
        public MailStrategyContext(List<MailStrategyService> mailServiceList) {
            log.info("开始注入策略");
            mailServiceList.forEach(mailServiceImpl -> {
                log.info("当前策略类:{}", mailServiceImpl.getClass().getName());
                strategy.put(mailServiceImpl.getServiceProviderName(), mailServiceImpl);
            });
            log.info("注入策略完毕");
        }
    
        /**
         * 发送邮件
         *
         * @param strategyName 策略名称
         * @param message      发送邮件信息
         */
        public void send(String strategyName, String message) {
            MailStrategyService mailStrategyService = strategy.get(strategyName);
            mailStrategyService.send(message);
        }
    }
    
    • StrategyController
    @RestController
    @RequestMapping("/mail")
    public class StrategyController {
        @Autowired
        private MailStrategyContext mailStrategy;
    
        @PostMapping("/{bussinessCode}/send")
        public void sendMail(@PathVariable(value = "bussinessCode") String bussinessCode,
                             @RequestParam(value = "message") String message) {
            mailStrategy.send(bussinessCode, message);
        }
    }
    
    • 使用PostMan测试
    • 发到QQ邮箱
      image.png
    image.png
    • 发到网易邮箱
      image.png
    image.png

    if-else,Goodbye!

    相关文章

      网友评论

        本文标题:Spring中如何实现策略模式

        本文链接:https://www.haomeiwen.com/subject/jgssuktx.html