Spring设计模式

Spring中如何实现策略模式

2020-09-29  本文已影响0人  AbstractCulture

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的实现类。实现具体的业务方法。

代码实现

public interface MailStrategyService {

    /**
     * 服务提供商名称
     *
     * @return
     */
    public String getServiceProviderName();

    /**
     * 发送邮件
     *
     * @param message
     */
    public void send(String message);

}
@Service
@Slf4j
public class NASDAQMailStrategyServiceImpl implements MailStrategyService {

    @Override
    public String getServiceProviderName() {
        return "ntes";
    }

    @Override
    public void send(String message) {
        log.info("现在向网易邮箱发送邮件:{}",message);
    }
}
@Service
@Slf4j
public class QQMailStrategyServiceImpl implements MailStrategyService {

    @Override
    public String getServiceProviderName() {
        return "qq";
    }

    @Override
    public void send(String message) {
       log.info("向QQ邮箱发送邮件:{}",message);
    }
}
@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);
    }
}
@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);
    }
}
image.png image.png

if-else,Goodbye!

上一篇 下一篇

猜你喜欢

热点阅读