JAVA設(shè)計模式中的策略模式你了解嗎
策略模式
世界上本沒有模式;
一些程序老鳥在長時間的編程工作總結(jié)出高效的代碼寫法被后世推崇;
并整理出固定的寫法規(guī)范,這個寫法規(guī)范目前收錄有23種
這些規(guī)范被稱之為 --> 設(shè)計模式
策略模式是什么
在策略模式(Strategy Pattern
)中,一個類的行為或其算法可以在運行時更改。這種類型的設(shè)計模式屬于行為型模式。
策略模式的使用場景
Q: 我們知道策略模式最重要的就是封裝變化點,那邊對于變化點我們一般用什么處理呢?
A: 是的 我們一般用if - else 處理需要對變化點做出不同的反應(yīng),策略模式就可以替換代碼中的if - else操作
其實策略模式主要就是替換代碼中的if - else操作,當(dāng)然也可以是switch
Q: 那我就有個疑問了,我就喜歡寫if - else switch,我為什么要用策略模式呢,難道就是為了看起來牛逼嗎?
A: 首先并不是所有的if - else switch 都適合使用策略模式改造,策略模式可謂是把雙刃劍,使用時也會帶來一些問題,比如說實現(xiàn)類膨脹;
Q: 既然是把雙刃劍,那么如何判斷是否應(yīng)該使用策略模式呢?
A: 策略模式對標(biāo)的是代碼中的if - else操作,主要針對if - else 的嵌套層級和每個if - else下的代碼處理行數(shù);
(你的if - else 判斷多余兩次) && (每個if - else 下的處理代碼超過5行) -> 建議使用策略模式優(yōu)化代碼
策略模式實踐
我們使用一個簡單的計算器需求來模擬策略模式的使用場景
/** * 計算器 * * @author cans * @date 2022/3/26 **/ public class Calculator { /** * 計算數(shù)字 * * @param num1 參數(shù)1 * @param num2 參數(shù)2 * @param operator 操作算法 * @return */ public Integer calculate(Integer num1, Integer num2, String operator) { if(operator.equals("+")){ return num1 + num2; }else if(operator.equals("-")){ return num1 - num2; } throw new RuntimeException("無效的操作算法"); } }
以上代碼使用if-else代碼實現(xiàn)了一個簡單的計算器代碼,實現(xiàn)也完全沒大問題,但是也存在弊端
1.擴展性不好,比如擴展乘法需要在代碼中追加if-else
2.一兩個if-else還好如果操作算法多了以后影響代碼的可讀性
下面使用策略模式對這個代碼進行優(yōu)化
/** * 使用策略模式進行優(yōu)化 * * @author cans * @date 2022/3/26 **/ public class Calculator2 { private Map<String,CalculatorOperator> calculatorOperatorMap = new HashMap<>(); public Calculator2(){ CalculatorOperatorAddImpl calculatorOperatorAdd = new CalculatorOperatorAddImpl(); CalculatorOperatorSubImpl calculatorOperatorSub = new CalculatorOperatorSubImpl(); calculatorOperatorMap.put(calculatorOperatorAdd.getOperator(),calculatorOperatorAdd); calculatorOperatorMap.put(calculatorOperatorSub.getOperator(),calculatorOperatorSub); } /** * 計算數(shù)字 * * @param num1 參數(shù)1 * @param num2 參數(shù)2 * @param operator 操作算法 * @return */ public Integer calculate(Integer num1, Integer num2, String operator) { CalculatorOperator calculatorOperator = calculatorOperatorMap.get(operator); if(calculatorOperator == null){ throw new RuntimeException("無效的操作算法:" + operator); } return calculatorOperator.calculate(num1, num2); } /** * 支持的算法枚舉 */ public enum Operator{ ADD("+"),SUB("-"); private String operator; Operator(String operator){ this.operator = operator; } public String getOperator() { return operator; } public void setOperator(String operator) { this.operator = operator; } } /** * 計算頂層接口 */ public interface CalculatorOperator{ /** * 算法操作 * @return */ public String getOperator(); /** * 計算方法 * * @param num1 參數(shù)1 * @param num2 參數(shù)2 * @return */ public Integer calculate(Integer num1, Integer num2); } /** * 加法實現(xiàn) */ public class CalculatorOperatorAddImpl implements CalculatorOperator{ @Override public String getOperator() { return Operator.ADD.getOperator(); } /** * 加法操作 * @param num1 參數(shù)1 * @param num2 參數(shù)2 * @return */ public Integer calculate(Integer num1, Integer num2) { return num1 + num2; } } /** * 減法實現(xiàn) */ public class CalculatorOperatorSubImpl implements CalculatorOperator{ @Override public String getOperator() { return Operator.SUB.getOperator(); } /** * 加法操作 * @param num1 參數(shù)1 * @param num2 參數(shù)2 * @return */ public Integer calculate(Integer num1, Integer num2) { return num1 - num2; } } @Test public void testCalculate(){ System.out.println("1+1 = : " + calculate(1,1,"+")); System.out.println("1-1 = : " + calculate(1,1,"-")); System.out.println("1*1 = : " + calculate(1,1,"*")); } }
策略模式以后類比較多,畫個簡單的圖方便理解
其實這里結(jié)合工廠模式更好用,使用Map calculatorOperatorMap
其實也一個意思;
可以看到使用策略模式以后類膨脹非常厲害,從之前1個類膨脹到4個類,但是擴展性得到了大大的提升,后續(xù)的算法擴展只需要在枚舉中新增枚舉類,實現(xiàn)響應(yīng)的算法實現(xiàn)即可;
綜上示例策略模式優(yōu)勢如下幾點:
1.擴展性提升;
2.主體業(yè)務(wù)邏輯更清晰;
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java使用CountDownLatch實現(xiàn)網(wǎng)絡(luò)同步請求的示例代碼
CountDownLatch 是一個同步工具類,用來協(xié)調(diào)多個線程之間的同步,它能夠使一個線程在等待另外一些線程完成各自工作之后,再繼續(xù)執(zhí)行。被將利用CountDownLatch實現(xiàn)網(wǎng)絡(luò)同步請求,異步同時獲取商品信息組裝,感興趣的可以了解一下2023-01-01Springboot集成Kafka實現(xiàn)producer和consumer的示例代碼
這篇文章主要介紹了Springboot集成Kafka實現(xiàn)producer和consumer的示例代碼,詳細(xì)的介紹了什么是Kafka和安裝Kafka以及在springboot項目中集成kafka收發(fā)message,感興趣的小伙伴們可以參考一下2018-05-05詳解Java編程中static關(guān)鍵字和final關(guān)鍵字的使用
這篇文章主要介紹了詳解Java編程中static關(guān)鍵字和final關(guān)鍵字的使用,是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09RestTemplate發(fā)送請求時Cookie的影響及注意事項說明
這篇文章主要介紹了RestTemplate發(fā)送請求時Cookie的影響及注意事項說明,具有很好的參考價值,希望對大家有所幫助。2023-07-07SpringCloud輪詢拉取注冊表與服務(wù)發(fā)現(xiàn)流程詳解
這篇文章主要介紹了SpringCloud輪詢拉取注冊表與服務(wù)發(fā)現(xiàn),現(xiàn)在很多創(chuàng)業(yè)公司都開始往springcloud靠了,可能是由于文檔和組件比較豐富的原因吧,畢竟是一款目前來說比較完善的微服務(wù)架構(gòu)2022-11-11