Springboot整合策略模式詳解
一、前言
策略模式可能是在工作中使用最多的,也是在面試中最常提到的,代碼重構(gòu)和優(yōu)化的必備!
小編之前也是一直說(shuō),其實(shí)沒(méi)有真正的實(shí)戰(zhàn);最近有了機(jī)會(huì)實(shí)戰(zhàn)了一下,來(lái)分享一下使用心得和在企業(yè)級(jí)的使用!
二、策略模式
1. 什么是策略模式
策略模式,英文全稱(chēng)是 Strategy Design Pattern
。在 GoF 的《設(shè)計(jì)模式》一書(shū)中,它是這樣定義的:
定義一族算法類(lèi),將每個(gè)
算法分別封裝起來(lái)
,讓它們可以互相替換
。策略模式可以使算法的變化獨(dú)立于使用它們的客戶(hù)端(這里的客戶(hù)端代指使用算法的代碼)。
2. 策略模式結(jié)構(gòu)組成
- Strategy:抽象策略類(lèi),一般為接口或者策略類(lèi)
- ConcreteStrategy:具體算法實(shí)現(xiàn)策略類(lèi)
- Context:環(huán)境或者上下文類(lèi),用于統(tǒng)一執(zhí)行具體策略
其實(shí)以上三部分用白話(huà)文來(lái)解釋就是:
需要一個(gè)接口和策略進(jìn)行規(guī)范和約束接口和方法,這時(shí)需要一些具體的實(shí)現(xiàn)算法類(lèi)去繼承或者實(shí)現(xiàn)剛剛的接口和策略,最后通過(guò)一個(gè)環(huán)境或者上下文,也可以叫做工廠根據(jù)類(lèi)型進(jìn)行調(diào)用具體的算法!
3. 使用場(chǎng)景
- 避免冗長(zhǎng)的 if-else 或 switch 分支判斷
- 需要?jiǎng)討B(tài)地在幾種算法中選擇一種
- 對(duì)客戶(hù)隱藏具體策略 (算法) 的實(shí)現(xiàn)細(xì)節(jié),彼此完全獨(dú)立,擴(kuò)展其余不受影響
具體場(chǎng)景一般為:
- 支付方式選擇
- 打折、滿(mǎn)減方式選擇
- 根據(jù)類(lèi)型調(diào)用不同的系統(tǒng)
4. 優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 擴(kuò)展性好
- 符合開(kāi)閉原則
- 符合單一職責(zé)原則
- 可讀性好
- 便于維護(hù)
- 避免多層判斷
缺點(diǎn):
- 策略過(guò)多,導(dǎo)致策略類(lèi)
- 對(duì)新手讀代碼不友好
三、策略模式實(shí)戰(zhàn)
1. 實(shí)戰(zhàn)例子
今天小編根據(jù)春夏秋冬四季需要做不同的事情來(lái)演示一下策略模式的使用方案;
需求是:
如果是春天,就要去放風(fēng)箏
如果是夏天,就要去游泳
如果是秋天,就要去看楓葉
如果是冬天,就要去打雪仗
沒(méi)有使用策略模式的話(huà),肯定就是
if-if else進(jìn)行實(shí)現(xiàn)!
下面就帶大家體會(huì)一下具體使用哈??!
2. 策略接口
/** * 四季策略 * @author wangzhenjun * @date 2022/12/1 9:30 */ public interface SeasonsStrategy { /** * 根據(jù)季節(jié)去執(zhí)行不同的方案 * @param seasons * @return */ String execute(String seasons); }
3. 春季具體實(shí)現(xiàn)
/** * 春季具體實(shí)現(xiàn) * @author wangzhenjun * @date 2022/12/1 9:34 */ // 指定容器的名稱(chēng),不指定默認(rèn)為類(lèi)名稱(chēng)首字母小寫(xiě) @Component("spring") public class SpringStrategy implements SeasonsStrategy{ @Override public String execute(String seasons) { return seasons + "來(lái)了!我們一起去放風(fēng)箏吧!"; } }
4. 夏季具體實(shí)現(xiàn)
/** * 夏季具體實(shí)現(xiàn) * @author wangzhenjun * @date 2022/12/1 9:34 */ // 指定容器的名稱(chēng),不指定默認(rèn)為類(lèi)名稱(chēng)首字母小寫(xiě) @Component("summer") public class SummerStrategy implements SeasonsStrategy{ @Override public String execute(String seasons) { return seasons + "來(lái)了!我們一起去游泳吧!"; } }
5. 秋季具體實(shí)現(xiàn)
/** * 秋季具體實(shí)現(xiàn) * @author wangzhenjun * @date 2022/12/1 9:34 */ // 指定容器的名稱(chēng),不指定默認(rèn)為類(lèi)名稱(chēng)首字母小寫(xiě) @Component("autumn") public class AutumnStrategy implements SeasonsStrategy{ @Override public String execute(String seasons) { return seasons + "來(lái)了!我們一起去放看楓葉吧!"; } }
6. 冬季具體實(shí)現(xiàn)
/** * 冬季具體實(shí)現(xiàn) * @author wangzhenjun * @date 2022/12/1 9:34 */ // 指定容器的名稱(chēng),不指定默認(rèn)為類(lèi)名稱(chēng)首字母小寫(xiě) @Component("winter") public class WinterStrategy implements SeasonsStrategy{ @Override public String execute(String seasons) { return seasons + "來(lái)了!我們一起去打雪仗吧!"; } }
7. 上下文工廠實(shí)現(xiàn)
private Map<String, SeasonsStrategy> seasonsMap;
這是最重要的,很多時(shí)候我們都知道怎么進(jìn)行策略和實(shí)現(xiàn)怎么寫(xiě),不知道怎么統(tǒng)一去放進(jìn)去,來(lái)進(jìn)行調(diào)用,可以自己放在map中。當(dāng)然spring已經(jīng)給我們組裝好了,只要按需調(diào)用即可!
核心:
Spring會(huì)自動(dòng)將Strategy接口的實(shí)現(xiàn)類(lèi)注入到這個(gè)Map中,key為bean id,value值則為對(duì)應(yīng)的策略實(shí)現(xiàn)類(lèi)!
/** * 環(huán)境或者上下文類(lèi),用于統(tǒng)一執(zhí)行具體策略 * @author wangzhenjun * @date 2022/12/1 9:56 */ @Component public class SeasonsFactory { /** * Spring會(huì)自動(dòng)將Strategy接口的實(shí)現(xiàn)類(lèi)注入到這個(gè)Map中,key為bean id,value值則為對(duì)應(yīng)的策略實(shí)現(xiàn)類(lèi) */ @Autowired private Map<String, SeasonsStrategy> seasonsMap; /** * 處理四季統(tǒng)一入口方法 * @param seasons * @param beanName * @return */ public String handle(String seasons,String beanName){ // 根據(jù)bean的名稱(chēng)獲取對(duì)應(yīng)的算法處理類(lèi) SeasonsStrategy seasonsStrategy = seasonsMap.get(beanName); String execute = seasonsStrategy.execute(seasons); return execute; } }
8. controller處理
@Slf4j @RestController @RequestMapping("/test") public class TestController { @Autowired private SeasonsFactory seasonsFactory; @GetMapping("/strategyTest/{seasons}/{beanName}") public Result strategyTest(@PathVariable("seasons") String seasons,@PathVariable("beanName") String beanName){ String handle = seasonsFactory.handle(seasons, beanName); return Result.success(handle); } }
9. 測(cè)試
http://localhost:8087/test/strategyTest/春天/spring
http://localhost:8087/test/strategyTest/夏天/summer
四、總結(jié)
在策略模式中定義了一系列算法,將每一個(gè)算法封裝起來(lái),并讓它們可以相互替換,互不影響。
策略模式得益于按照開(kāi)閉原則
進(jìn)行設(shè)計(jì),各個(gè)具體算法按照單一職責(zé)原則
設(shè)計(jì); 提高了代碼的復(fù)用性
,對(duì)客戶(hù)隱藏具體策略 (算法) 的實(shí)現(xiàn)細(xì)節(jié),彼此完全獨(dú)立,擴(kuò)展其余不受影響;避免if-else 或 switch 分支
語(yǔ)句判斷;其缺點(diǎn)在于客戶(hù)端必須知道所有的策略類(lèi),增加了系統(tǒng)中類(lèi)的個(gè)數(shù)。
在日常開(kāi)發(fā)一般用于消除多重判斷,有時(shí)候不要為了用設(shè)計(jì)模式而用設(shè)計(jì)模式
,一定要結(jié)合業(yè)務(wù)場(chǎng)景,過(guò)度設(shè)計(jì)
也是很致命的?。?/p>
如果對(duì)你有幫助,還請(qǐng)不要吝嗇您的發(fā)財(cái)小手,你的一鍵三連是我寫(xiě)作的動(dòng)力,謝謝大家哈??!
到此這篇關(guān)于Springboot整合策略模式詳解的文章就介紹到這了,更多相關(guān)Springboot整合策略模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot如何使用@Aspect注解實(shí)現(xiàn)AOP
這篇文章主要介紹了SpringBoot如何使用@Aspect注解實(shí)現(xiàn)AOP問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07java實(shí)現(xiàn)文件上傳下載至ftp服務(wù)器
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)文件上傳下載至ftp服務(wù)器的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06SpringBoot中實(shí)現(xiàn)訂單30分鐘自動(dòng)取消的項(xiàng)目實(shí)踐
現(xiàn)在電子商務(wù)平臺(tái)上訂單創(chuàng)建成功,等待支付,一般會(huì)給30分鐘的時(shí)間,本文主要介紹了SpringBoot中實(shí)現(xiàn)訂單30分鐘自動(dòng)取消的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10SpringBoot+WebSocket+Netty實(shí)現(xiàn)消息推送的示例代碼
這篇文章主要介紹了SpringBoot+WebSocket+Netty實(shí)現(xiàn)消息推送的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04