建設(shè)部繼續(xù)教育網(wǎng)站網(wǎng)站制作方案
函數(shù)式接口實(shí)現(xiàn)策略模式
1.案例背景
我們在日常開發(fā)中,大多會(huì)寫if、else if、else 這樣的代碼,但條件太多時(shí),往往嵌套無數(shù)層if else,閱讀性很差,比如如下案例,統(tǒng)計(jì)學(xué)生的數(shù)學(xué)課程的成績:
- 90-100分,打印【優(yōu)秀A+】
- 80-90分,打印【優(yōu)秀A-】
- 70-80分,打印【中等B+】
- 60-70,打印【中等B-】
- 60及以下,打印【同學(xué)還需努力!】
我們會(huì)寫如下代碼:
// 0<=grade<=100if (grade > 90 && grade <= 100) {System.out.println("【優(yōu)秀A+】");} else if (grade > 80 && grade <= 90) {System.out.println("【優(yōu)秀A-】");} else if (grade > 70 && grade <= 80) {System.out.println("【中等B+】");} else if (grade > 60 && grade <= 70) {System.out.println("【中等B-】");} else {System.out.println("【同學(xué)還需努力!】 ");}
毋庸置疑,上述代碼完全正確,可以滿足業(yè)務(wù)要求,但考慮到未來業(yè)務(wù)的擴(kuò)展性與代碼的可閱讀性,大量的if、else語句使代碼不夠優(yōu)雅,隨著后續(xù)業(yè)務(wù)的增加,分類可能越來越細(xì),豈不是要嵌套成百上千層。接下來考慮使用函數(shù)式接口+策略模式的思想完成代碼改造。
2.代碼改造
2.1 創(chuàng)建函數(shù)式策略接口
創(chuàng)建自定義函數(shù)式策略接口:
/*** 函數(shù)式策略接口*/
@FunctionalInterface
public interface GradeFuncInterface {/*** 打印成績方法* @param grade 實(shí)際成績*/void printStudentGrade(Integer grade);
}
2.2 創(chuàng)建策略方法類
創(chuàng)建策略方法類,相關(guān)注釋已在代碼中標(biāo)注:
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;/*** 策略方法*/
public class GradeStrategy {/*** 存儲(chǔ)策略邏輯* 這里使用到了另外一個(gè)JDK提供的函數(shù)式接口,Predicate,里面幾個(gè)方法很簡單,大家感興趣可以點(diǎn)進(jìn)去閱讀下底層源碼*/private final Map<Predicate<Integer>, GradeFuncInterface> gradeMap = new HashMap<>();/*** 無參構(gòu)造*/public GradeStrategy() {gradeMap.put(grade -> this.determineGrade(grade, 100, 90), ((grade) -> System.out.println("【優(yōu)秀A+】")));gradeMap.put(grade -> this.determineGrade(grade, 90, 80), ((grade) -> System.out.println("【優(yōu)秀A-】")));gradeMap.put(grade -> this.determineGrade(grade, 80, 70), ((grade) -> System.out.println("【中等B+】")));gradeMap.put(grade -> this.determineGrade(grade, 70, 60), ((grade) -> System.out.println("【中等B-】")));gradeMap.put(grade -> this.determineGrade(grade, 60, -1), ((grade) -> System.out.println("【同學(xué)還需努力!】")));}/*** 判斷成績的區(qū)間* @param grade 實(shí)際成績* @param maxGrade 最大成績* @param minGrade 最小成績* @return*/private boolean determineGrade(Integer grade, Integer maxGrade, Integer minGrade) {if (grade > minGrade && grade <= maxGrade) {return true;}return false;}/*** 獲取成績區(qū)間* @param grade*/public void getStudentGrade(Integer grade) {// 遍歷策略mapfor (Map.Entry<Predicate<Integer>, GradeFuncInterface> entry : gradeMap.entrySet()) {if (entry.getKey().test(grade)) {entry.getValue().printStudentGrade(grade);return;}}System.out.println("學(xué)生成績?yōu)?#xff1a;" + grade + "無對應(yīng)期間成績,請維護(hù)!");}
}
3. 測試
3.1 創(chuàng)建測試類
測試類代碼如下:
public class StrategyTest {public static void main(String[] args) {GradeStrategy gradeStrategy = new GradeStrategy();gradeStrategy.getStudentGrade(98);gradeStrategy.getStudentGrade(88);gradeStrategy.getStudentGrade(78);gradeStrategy.getStudentGrade(68);gradeStrategy.getStudentGrade(58);gradeStrategy.getStudentGrade(128);gradeStrategy.getStudentGrade(-18);}}
3.2 運(yùn)行結(jié)果
通過運(yùn)行結(jié)果,可知輸出結(jié)果正確。
4. 總結(jié)
通過策略模式的思想+函數(shù)式接口,我們將大量的if else判斷分解出來,在調(diào)用端只需要調(diào)用策略類提供的方法,使代碼更加優(yōu)雅,當(dāng)業(yè)務(wù)需要擴(kuò)展時(shí),我們只需要加上對應(yīng)策略即可,使我們只用注重業(yè)務(wù)邏輯層的代碼,讓運(yùn)維更加方便簡潔。
備注:另外一種策略模式的使用見:工廠模式+策略模式