今天咱們來了解下設計模式中比較經常使用的策略模式算法
策略模式定義了一系列的算法,並將每個算法封裝起來,使每一個算法能夠相互替代,使算法自己和使用算法的客戶端分割開來,相互獨立。(摘自百度)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去管理,只管加就好了