1.概述
本篇文章主要會描述SpringBoot與策略模式的結(jié)合使用,因為不涉及到理論部分,所以在閱讀本篇之前,需要對策略模式的理論已經(jīng)有了一個基本的了解。
1.1.簡述策略模式
策略模式有3種角色,分別為:選擇器、抽象策略、策略實例。
其中選擇器selector
又被稱為上下文context
,其作用為通過不同的標(biāo)識來獲取對應(yīng)的策略實例。策略實例就是封裝不同算法的實例對象,而抽象策略就是策略實例的頂層接口。
簡單類圖大概就是這個樣子:
2.實現(xiàn)方法
我們在學(xué)習(xí)設(shè)計模式的時候會發(fā)現(xiàn)在各類模式中的類與對象都是手動創(chuàng)建的,而在日常的開發(fā)中,我們往往會將對象的生命周期交給Spring管理,也就是說,需要我們自行將各類bean
組合成一個可運行的設(shè)計模式。
假設(shè)我們有這樣一個場景,需要對系統(tǒng)的中的數(shù)據(jù)做統(tǒng)計,需求中的統(tǒng)計維度分為:按周統(tǒng)計、按月統(tǒng)計,現(xiàn)使用策略模式來實現(xiàn)這個需求。
2.1.實現(xiàn)思路
- 前置設(shè)計:通過定義常量來標(biāo)識策略的類型,使用者調(diào)用時可以通過常量獲取對應(yīng)的策略實例。
- 策略設(shè)計:按周、按月分別對應(yīng)兩個
bean
實例,在內(nèi)部各自實現(xiàn)對應(yīng)的統(tǒng)計維度邏輯,在兩個bean
實例的上層是抽象策略,有一個通用的接口(或抽象類)用于對外提供訪問入口。 - 選擇器設(shè)計:可以通過
Map
來存儲數(shù)據(jù),調(diào)用者調(diào)用時可以通過策略標(biāo)識來獲取對應(yīng)的策略實例。
可以看到,實現(xiàn)思路是比較簡單的,現(xiàn)在的問題就是如何把策略的bean
實例對象放到Map
中。
最簡單的方式當(dāng)然就是把對應(yīng)的bean
的Class
對象直接寫死在Map
中,調(diào)用的時候可以通過applicationContext.getBean()
獲取到bean
實例。但是這種方式不利于拓展,后續(xù)要新增一個策略實例的時候,還得修改這里的Map
。
第二種方式,我們可以通過解析注解來實現(xiàn),給每個策略實例打上一個注解,注解中的值對應(yīng)的就是按周、按月這樣的常量標(biāo)識,在SpringBoot啟動時,通過擴(kuò)展點掃描抽象策略,獲取它所有的策略實例,解析注解后放入Map
中。這種方式利于拓展,新增一個策略實例不需要對舊代碼有任何改動。
2.2.實現(xiàn)代碼
這里原本是使用自定義注解來實現(xiàn)的,經(jīng)過評論區(qū)的提醒,對于注解實現(xiàn)這種方式,通過Spring中自帶的@Component
注解來實現(xiàn)會更加簡潔,下面是去掉了自定義注解的實現(xiàn)方式。
- 第一步:編寫抽象策略與策略實例
/** * 統(tǒng)計抽象策略處理器 */ public interface StatisticBaseHandler { void doStatistic(); }
import org.springframework.stereotype.Component; /** * 月統(tǒng)計策略 */ @Component("month") public class StatisticByMonthHandler implements StatisticBaseHandler { @Override public void doStatistic() { System.out.println("StatisticByMonthHandler"); } }
import org.springframework.stereotype.Component; /** * 周統(tǒng)計策略 */ @Component("week") public class StatisticByWeekHandler implements StatisticBaseHandler { @Override public void doStatistic() { System.out.println("StatisticByWeekHandler"); } }
- 第二步:編寫選擇器
這里直接使用@Resouce
或者@Autowired
注入一個Map
。import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.Map; /** * 統(tǒng)計策略選擇器 */ @Component public class StatisticStrategySelector { @Resource private Map<String, StatisticBaseHandler> selectorMap; /** * 根據(jù)類型選擇對應(yīng)的策略 * * @param type 統(tǒng)計周期類型 * @return 統(tǒng)計抽象策略處理器 */ public StatisticBaseHandler select(String type) { return selectorMap.get(type); } }
啟動完成之后,Map
中的key值為@Component
中配置的key
。
2.3.策略拓展
現(xiàn)在需求發(fā)生了變化,需要加入一個按年統(tǒng)計的策略類型,只需要新增一個策略實例即可,如下:
import org.springframework.stereotype.Component;
/**
* 年統(tǒng)計策略
*/
@Component("year")
public class StatisticByYearHandler implements StatisticBaseHandler {
@Override
public void doStatistic() {
System.out.println("StatisticByYearHandler");
}
}
其他的代碼都不需要修改,再次查看Map
中的值:
2.4.執(zhí)行調(diào)用
隨便寫了一個測試方法,如下:
public void invoke() {
this.doInvoke("week");
this.doInvoke("month");
this.doInvoke("year");
}
public void doInvoke(String type) {
StatisticBaseHandler handler = select(type);
handler.doStatistic();
}
分別打印出了按周統(tǒng)計、按月統(tǒng)計、按年統(tǒng)計方法中的輸出值,表示策略模式定義成功了,在我們實際的開放中,只需要前端(或其他調(diào)用端)傳入對用的標(biāo)識字符串,就可以執(zhí)行不同的統(tǒng)計邏輯了。文章來源:http://www.zghlxwxcb.cn/news/detail-495046.html
3.總結(jié)
通過Spring獲取接口的實現(xiàn),并解析實現(xiàn)類上的注解的方式,可以在程序啟動時動態(tài)的將策略注入到一個Map
中,作為策略的容器。使用時傳入標(biāo)識符
就可以獲取到對應(yīng)的策略執(zhí)行了。文章來源地址http://www.zghlxwxcb.cn/news/detail-495046.html
到了這里,關(guān)于【設(shè)計模式】SpringBoot優(yōu)雅使用策略模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!