今天咱们来了解下设计模式中比较经常使用的策略模式算法
策略模式定义了一系列的算法,并将每个算法封装起来,使每一个算法能够相互替代,使算法自己和使用算法的客户端分割开来,相互独立。(摘自百度)spring
一个大功能,它有许多不一样类型的实现(策略类),具体根据客户端来决定采用特定的策略类。 好比下单、物流对接、网关的加签验签等。设计模式
具体业务为每一个物流公司都有它们对应的code,加签方法,物流查询方法app
首先咱们定义好接口类ide
public interface Logistics { /** * 物流公司惟一标识 * @return */ String companyCode(); /** * 加签 * @param request */ String sign(SignRequest request); /** * 查询物流信息 */ LogisticsInfoResponse queryLogisticsInfo(QueryLogisticsInfoRequest request); }
对接顺风和圆通this
@service("shunfengLogistics") public class ShunfengLogistics implements Logistics { @Override public String companyCode() { return "shunfeng"; } @Override public String sign(SignRequest request) { //do your biz return null; } @Override public LogisticsInfoResponse queryLogisticsInfo(QueryLogisticsInfoRequest request) { //do your biz return null; } } @service("yuantongLogistics") public class YuantongLogistics implements Logistics { @Override public String companyCode() { return "yuantong"; } @Override public String sign(SignRequest request) { //do your biz return null; } @Override public LogisticsInfoResponse queryLogisticsInfo(QueryLogisticsInfoRequest request) { //do your biz return null; } }
public class LogisticsFactory { @Autowired private Logistics shunfengLogistics; @Autowired private Logistics yuantongLogistics; public Logistics getLogistics(LogisticsRequest request) { String company = request.getCompanyCode(); if ("shunfeng".equals(company)) { return shunfengLogistics; } if ("yuantong".equals(company)) { return yuantongLogistics; } throw new BizException("物流公司类型错误"); } }
每当咱们接入一家物流公司的时候都要使LogisticsFactory加一段if分支。这就违反了设计模式的开闭原则spa
其实不结合Spring特性的话,策略模式仍是有上述问题存在。 咱们先来准备下spring相关知识设计
1.实现InitializingBean接口。相信这个你们并不陌生。就是spring容器建立bean的时候帮你执行初始化的接口code
2.实现ApplicationContextAware接口。通俗的讲,实现了这个接口的bean至关因而拿到了ApplicationContext,至关于整个spring容器的资源。接口
3.ApplicationContext接口的getBeansOfType方法。获取整个spring容器中某个类型的bean,返回的是map类型。key对应beanName, value对应bean。
@Component public class LogisticsResolver implements InitializingBean, ApplicationContextAware { private ApplicationContext applicationContext; private Map<String, Sign> logisticsHandlerMap = new HashMap<>(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void afterPropertiesSet() { Map<String, Sign> beanMap = applicationContext.getBeansOfType(Logistics.class); for (String key : beanMap.keySet()) { this.logisticsHandlerMap.put(beanMap.get(key).companyCode(), beanMap.get(key)); } } public Logistics getHandler(String companyCode) { return logisticsHandlerMap.get(companyCode); } }
经过spring容器去获取对应的全部实现类,并组装成咱们想要的companyCode→bean的map。经过getHandler方法就能拿到对应的实现类。
可是如今咱们每次加一个策略类的时候都交由Spring去管理,只管加就好了