結合Spring特性實現策略模式

今天咱們來了解下設計模式中比較經常使用的策略模式算法

什麼是策略模式?

策略模式定義了一系列的算法,並將每個算法封裝起來,使每一個算法能夠相互替代,使算法自己和使用算法的客戶端分割開來,相互獨立。(摘自百度)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特性的話,策略模式仍是有上述問題存在。 咱們先來準備下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去管理,只管加就好了

相關文章
相關標籤/搜索