最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java去除if...else的七種方法總結(jié)

 更新時(shí)間:2023年11月08日 11:07:02   作者:大明哥_  
相信小伙伴一定看過(guò)多篇怎么去掉?if...else?的文章,也知道大家都很有心得,知道多種方法來(lái)去掉?if...else?,本文為大家整理了7個(gè)常用的方法,希望對(duì)大家有所幫助

方法一:提前 return

假如有如下代碼:

if (condition){
  doSomething;
} else {
  return;
}

這種代碼我們一般采用提前 return 的方式,去掉不必要的 else。

if (!condition){
  return
}

doSomething;

這種方法一般只適合分支結(jié)構(gòu)很簡(jiǎn)單的 if...else,我們可以提前 return ,把一些不必要的 if...else 去掉。

方法二:枚舉

枚舉其實(shí)也是可以去掉 if...else 的,如下:

String orderStatusDes;
if ("1".equals(orderStatus)) {
    orderStatusDes = "訂單未支付";
} else if ("2".equals(orderStatus)) {
    orderStatusDes = "訂單已支付";
} else if ("3".equals(orderStatus)) {
    orderStatusDes = "訂單已發(fā)貨";
} else if ("4".equals(orderStatus)) {
    orderStatusDes = "訂單已簽收";
} else if ("5".equals(orderStatus)) {
    orderStatusDes = "訂單已評(píng)價(jià)";
}

可能有小伙伴說(shuō),靠,誰(shuí)會(huì)寫(xiě)這種代碼?別這么絕對(duì),大明哥工作這么久了,到現(xiàn)在依然看到有工作 5 、6 年的人寫(xiě)這樣的代碼。這種類型的代碼非常適合枚舉來(lái)解決。

先定義一個(gè)枚舉類:

@Getter
@AllArgsConstructor
public enum OrderStatusEnum {
    UN_PAID("1","訂單未支付"),
    PAIDED("2","訂單已支付"),
    SENDED("3","訂單已發(fā)貨"),
    SINGED("4","訂單已簽收"),
    EVALUATED("5","訂單已評(píng)價(jià)");

    private String status;

    private String statusDes;

    static OrderStatusEnum of(String status) {
        for (OrderStatusEnum statusEnum : OrderStatusEnum.values()) {
            if (statusEnum.getStatus().equals(status)) {
                return statusEnum;
            }
        }
        return null;
    }
}

有了這個(gè)枚舉,上面代碼直接可以優(yōu)化為一行代碼:

String orderStatusDes = OrderStatusEnum.of(orderStatus).getStatusDes();

當(dāng)然一般在實(shí)際項(xiàng)目中,這種處理方式也不是最佳的,最佳的方式應(yīng)該是在數(shù)據(jù)庫(kù)里面有一個(gè)碼值配置表,然后加載到系統(tǒng)緩存中來(lái),在通過(guò) code 去取值。當(dāng)然枚舉也是一種很好的解決方案。

方案三:Optional 判空

我相信各位小伙伴的項(xiàng)目里面一定存在非空判斷,如果為空,則拋出異?;蛘?return。

Order order = getOrderById(id);
if (order == null) {
    return "-1";
} else {
    return order.getOrderStatus();
}

對(duì)于這種代碼我們利用 Optional 可以非常優(yōu)雅地解決。

return Optional.ofNullable(order).map(o -> o.getOrderStatus()).orElse("-1");

這種方式是不是非常優(yōu)雅,有格調(diào)。最后補(bǔ)充一句:

防止 NPE,是程序員的基本修養(yǎng)

方案四:表驅(qū)動(dòng)法

表驅(qū)動(dòng)法,是一種讓你可以在表中查找信息,而不必用過(guò)多的 if...else 來(lái)把他們找出來(lái)的方法。如下:

if ("code1".equals(action)) {
    doAction1();
} else if ("code2".equals(action)) {
    doAction2();
} else if ("code3".equals(action)) {
    doAction3();
} else if ("code4".equals(action)) {
    doAction4();
} else if ("code5".equals(action)) {
    doAction5();
}

優(yōu)化方法如下:

Map<String, Function<?> action> actionMap = new HashMap<>();
action.put("code1",() -> {doAction1()});
action.put("code2",() -> {doAction2()});
action.put("code3",() -> {doAction3()});
action.put("code4",() -> {doAction4()});
action.put("code5",() -> {doAction5()});

// 使用
actionMap.get(action).apply();

其實(shí)這種方式也不是很好,因?yàn)樗鼤?huì)顯得代碼非常臃腫。一種變形方案是將 doAction() 抽象成類。如下:

//1. 先定義一個(gè) ActionService 接口
public interface ActionService {
    void doAction();
}

//2. 然后定義 5 個(gè)實(shí)現(xiàn)類
public class ActionService1 implements ActionService{
    public void doAction() {
        //do something
    }
}

//3. 加入表中
Map<String, ActionService> actionMap = new HashMap<>();
action.put("code1",new ActionService1());
action.put("code2",new ActionService2());
action.put("code3",new ActionService3());
action.put("code4",new ActionService4());
action.put("code5",new ActionService5());

//4. 調(diào)用
actionMap.get(action).doAction();

這種方式是不是比較優(yōu)雅些!

方案五:策略模式 + 工廠方法

策略模式 + 工廠方法是解決 if...else 用得非常多的方案,它和上面的表驅(qū)動(dòng)法有點(diǎn)兒類似。使用策略模式 + 工廠方法分為幾個(gè)步驟,以上面例子為例:

把條件模塊抽象為一個(gè)公共的接口,策略接口

public interface ActionService {
    void doAction();
}

根據(jù)每個(gè)邏輯,定義出自己具體的策略實(shí)現(xiàn)類,如下:

public class ActionService1 implements ActionService{
    public void doAction() {
        //do something
    }
}

public class ActionService2 implements ActionService{
    public void doAction() {
        //do something
    }
}

// 省略其他策略

工廠類,統(tǒng)一調(diào)度,用來(lái)管理這些策略,如下:

public class ActionServiceFactory {
    private ActionServiceFactory(){

    }

    private static class SingletonHolder{
        private static ActionServiceFactory instance=new ActionServiceFactory();
    }

    public static ActionServiceFactory getInstance(){
        return SingletonHolder.instance;
    }

    private static final Map<String,ActionService> ACTION_SERVICE_MAP = new HashMap<String, ActionService>();

    static {
        ACTION_SERVICE_MAP.put("action1",new ActionService1());
        ACTION_SERVICE_MAP.put("action2",new ActionService2());
        ACTION_SERVICE_MAP.put("action3",new ActionService3());
        ACTION_SERVICE_MAP.put("action4",new ActionService4());
        ACTION_SERVICE_MAP.put("action5",new ActionService5());
    }

    public static ActionService getActionService(String actionCode) {
        ActionService actionService = ACTION_SERVICE_MAP.get(actionCode);
        if (actionService == null) {
            throw new RuntimeException("非法 actionCode");
        }
        return actionService;
    }

    public void doAction(String actionCode) {
        getActionService(actionCode).doAction();
    }
}

單例模式實(shí)現(xiàn)工廠類。

使用

ActionServiceFactory.getInstance().doAction("action1");

這種優(yōu)化方式也是很優(yōu)雅的,特別適合分支較多,邏輯較為復(fù)雜的代碼塊,這種方式將分支邏輯與業(yè)務(wù)代碼解耦了,是一種很不錯(cuò)的方案。

方案六:責(zé)任鏈模式

你想不到責(zé)任鏈模式也能優(yōu)化 if...else 吧。責(zé)任鏈我們可以看做是一個(gè)單鏈表的數(shù)據(jù)結(jié)構(gòu),一個(gè)對(duì)象一個(gè)對(duì)象地過(guò)濾條件,符合的就執(zhí)行,然后結(jié)束,不符合的就傳遞到下一個(gè)節(jié)點(diǎn),如果每個(gè)對(duì)象都無(wú)法處理,一般都有一個(gè)最終的節(jié)點(diǎn)來(lái)統(tǒng)一處理。

我們依然以上面那個(gè)例子為例。

定義責(zé)任鏈處理請(qǐng)求節(jié)點(diǎn)

public abstract class ActionHandler {

    // 后繼節(jié)點(diǎn)
    protected ActionHandler successor;

    /**
     * 處理請(qǐng)求
     * @param actionCode
     */
    public void handler(String actionCode) {
        doHandler(actionCode);
    }

    // 設(shè)置后繼節(jié)點(diǎn)
    protected ActionHandler setSuccessor(ActionHandler successor) {
        this.successor = successor;
        return this;
    }

    // 處理請(qǐng)求
    public abstract void doHandler(String actionCode);
}

定義首尾節(jié)點(diǎn),用于一些異常情況的處理

// 首節(jié)點(diǎn),判斷 actionCode 是否為空
public class HeadHandler extends ActionHandler{

    @Override
    public void doHandler(String actionCode) {
        if (StringUtils.isBlank(actionCode)) {
            throw new RuntimeException("actionCode 不能為空");
        }

        successor.doHandler(actionCode);
    }
}

// 尾節(jié)點(diǎn),直接拋出異常,因?yàn)榈搅宋补?jié)點(diǎn)說(shuō)明當(dāng)前 code 沒(méi)有處理
public class TailHandler extends ActionHandler{

    @Override
    public void doHandler(String actionCode) {
        throw new RuntimeException("當(dāng)前 code[" + actionCode + "] 沒(méi)有具體的 Handler 處理");
    }
}

定義各個(gè)節(jié)點(diǎn)具體的實(shí)現(xiàn)節(jié)點(diǎn)

public class ActionHandler1 extends ActionHandler{

    @Override
    public void doHandler(String actionCode) {
        if ("action1".equals(actionCode)) {
            doAction1();
        } else {
            // 傳遞到下一個(gè)節(jié)點(diǎn)
            successor.doHandler(actionCode);
        }
    }
}

public class ActionHandler2 extends ActionHandler{

    @Override
    public void doHandler(String actionCode) {
        if ("action2".equals(actionCode)) {
            doAction2();
        } else {
            // 傳遞到下一個(gè)節(jié)點(diǎn)
            successor.doHandler(actionCode);
        }
    }
}

// 省略其他節(jié)點(diǎn)

定義工廠,來(lái)構(gòu)建一條完整的責(zé)任鏈,并負(fù)責(zé)調(diào)度

public class ActionHandlerFactory {
    
    private ActionHandler headHandler;
    
    private ActionHandlerFactory(){
        headHandler = new HeadHandler();
        ActionHandler actionHandler1 = new ActionHandler1();
        ActionHandler actionHandler2 = new ActionHandler2();
        ActionHandler actionHandler3 = new ActionHandler3();
        ActionHandler actionHandler4 = new ActionHandler4();
        ActionHandler actionHandler5 = new ActionHandler5();

        ActionHandler tailHandler = new TailHandler();
        
        // 構(gòu)建一條完整的責(zé)任鏈
        headHandler.setSuccessor(actionHandler1).setSuccessor(actionHandler2).setSuccessor(actionHandler3).
                setSuccessor(actionHandler4).setSuccessor(actionHandler5).setSuccessor(tailHandler);
    }

    private static class SingletonHolder{
        private static ActionHandlerFactory instance=new ActionHandlerFactory();
    }

    public static ActionHandlerFactory getInstance(){
        return SingletonHolder.instance;
    }
        
    public void doAction(String actionCode) {
        headHandler.doHandler(actionCode);
    }
}

使用

ActionHandlerFactory.getInstance().doAction("action1");

方案七:Function

Function 是 Java 8 中的函數(shù)式接口,利用好它我們可以極大地簡(jiǎn)化我們的代碼,例如利用它我們可以輕松去掉我們的 if...else。比如有下面一段代碼:

// 拋出異常
if (...) {
  throw new RuntimeException("哎呀,有異常哦...")
}

// if...else 分支
if(...) {
  doSomething1();
} else {
  doSomething2();
}

現(xiàn)在我們利用 Function 來(lái)處理上面兩段代碼

處理拋出異常

定義拋出異常的形式的函數(shù)式接口

@FunctionalInterface
public interface ThrowExceptionFunction {

    /**
     * 拋出異常
     * @param message
     */
    void throwMessage(String message);
}

這里只需要有一個(gè)這樣的函數(shù)式接口就行,而且方法也沒(méi)有返回值,是一個(gè)消費(fèi)型接口。

增加判斷工具類

public class ValidateUtils {

    /**
     * 拋出異常
     * @param flag
     * @return
     */
    public static ThrowExceptionFunction isTrue(Boolean flag) {
        return (errorMessage) -> {
            if (flag) {
                throw new RuntimeException(errorMessage);
            }
        };
    }
}

ValidateUtils 類也是非常簡(jiǎn)單的,如果傳入的 flag 為 true,則拋出異常。isTrue() 返回值也是剛剛我們定義的 ThrowExceptionFunction。

使用

ValidateUtils.isTrue(flag).throwMessage("哎呀,有異常哦...");

使用方式是不是非常簡(jiǎn)單?

處理 if...else 分支

其實(shí)使用 Function 來(lái)去掉 if...else 分支我認(rèn)為有點(diǎn)兒偏門(mén),因?yàn)樗浅R蕾囄覀兌x的 Function 函數(shù),比如我們定義的方法只有兩個(gè)參數(shù),那它就只能處理處理兩個(gè)分支的,對(duì)于三個(gè)分支的 if...else 則需要重新定義方法。下面以兩個(gè)分支為例。

定義函數(shù)式接口

@FunctionalInterface
public interface ActionHandler {
    void doActionHandler(ActionService trueActionService,ActionService falseActionService);
}

函數(shù)式接口中定義了一個(gè)方法,doActionHandler(),它有兩個(gè)參數(shù),分別為:

  • trueActionService:為 true 時(shí)要進(jìn)行的操作
  • falseActionService:為 false 時(shí)要進(jìn)行的操作

定義判斷方法

增加一個(gè)工具類,用來(lái)判斷為 true 時(shí)執(zhí)行哪個(gè)方法,為 false 時(shí)執(zhí)行哪個(gè)方法。

public class ActionHandlerUtils {

    public static ActionHandler isTrue(Boolean flag) {
        return (trueActionService,falseActionService) -> {
            if (flag) {
                trueActionService.doAction();
            } else {
                trueActionService.doAction();
            }
        };
    }
}

使用

ActionHandlerUtils.isTrue(true)
        .doActionHandler(() -> {
            //do true Something
        },() ->{
            //do false Something
    });

總結(jié)

大明哥在這里總結(jié)了 7 中方式用來(lái)解決 if...else 的問(wèn)題,我相信里面總有一兩種方案是你比較滿意的,七種方案各有優(yōu)劣,各自有各自的使用場(chǎng)景,我們需要在實(shí)踐中不斷領(lǐng)悟,在重構(gòu)中不斷進(jìn)化,總結(jié)出適合自己最佳的重構(gòu)方案。

到此這篇關(guān)于java去除if...else的七種方法總結(jié)的文章就介紹到這了,更多相關(guān)java去除if else內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot后端解決跨域問(wèn)題

    springboot后端解決跨域問(wèn)題

    今天小編就為大家分享一篇關(guān)于springboot后端解決跨域問(wèn)題,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • Java8新特性之默認(rèn)方法詳解

    Java8新特性之默認(rèn)方法詳解

    JAVA8 所提供的默認(rèn)方法,就是在接口上你可以定義某些方法的實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Java8新特性之默認(rèn)方法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Spring?Data?JPA框架快速入門(mén)之自定義Repository接口

    Spring?Data?JPA框架快速入門(mén)之自定義Repository接口

    Spring?Data?JPA是Spring基于JPA規(guī)范的基礎(chǔ)上封裝的?套?JPA?應(yīng)?框架,可使開(kāi)發(fā)者?極簡(jiǎn)的代碼即可實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)和操作,本篇我們來(lái)了解Spring?Data?JPA框架的自定義Repository接口
    2022-04-04
  • 記錄jdk21連接SQLServer因?yàn)門(mén)LS協(xié)議報(bào)錯(cuò)問(wèn)題

    記錄jdk21連接SQLServer因?yàn)門(mén)LS協(xié)議報(bào)錯(cuò)問(wèn)題

    在使用Druid連接池連接SQL Server時(shí),可能會(huì)遇到因TLS版本不匹配導(dǎo)致的連接失敗問(wèn)題,具體表現(xiàn)為客戶端使用TLS1.3或TLS1.2,而SQL Server僅支持TLS1.0,導(dǎo)致無(wú)法建立安全連接,解決方法是修改JDK的安全配置,啟用TLS1.0
    2024-10-10
  • SpringBoot集成iText快速生成PDF教程

    SpringBoot集成iText快速生成PDF教程

    本文介紹了如何在SpringBoot項(xiàng)目中集成iText9.4.0生成PDF文檔,包括新特性的介紹、環(huán)境準(zhǔn)備、Service層實(shí)現(xiàn)、Controller編寫(xiě)、優(yōu)劣分析、不同版本對(duì)比、版本選擇建議以及最佳實(shí)踐總結(jié)
    2025-11-11
  • Tomcat+JDK安裝和配置教程

    Tomcat+JDK安裝和配置教程

    這篇文章主要為大家詳細(xì)介紹了Tomcat+JDK安裝和配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Java8新特性之Stream API詳解

    Java8新特性之Stream API詳解

    這篇文章主要介紹了Java8新特性之StreamAPI詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java向上向下轉(zhuǎn)型詳解

    Java向上向下轉(zhuǎn)型詳解

    這篇文章主要為大家詳細(xì)介紹了Java向上向下轉(zhuǎn)型,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Java編程中的vector類用法學(xué)習(xí)筆記

    Java編程中的vector類用法學(xué)習(xí)筆記

    Vector通常被用來(lái)實(shí)現(xiàn)動(dòng)態(tài)數(shù)組,即可實(shí)現(xiàn)自動(dòng)增長(zhǎng)的對(duì)象數(shù)組,和C++一樣vector類同樣被Java內(nèi)置,下面就來(lái)看一下vector類的基本用法.
    2016-05-05
  • 詳解通過(guò)maven運(yùn)行項(xiàng)目的兩種方式

    詳解通過(guò)maven運(yùn)行項(xiàng)目的兩種方式

    這篇文章主要介紹了通過(guò)maven運(yùn)行項(xiàng)目的兩種方式,給大家提到了通過(guò)tomcat的方式來(lái)啟動(dòng)maven項(xiàng)目的方法,通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-12-12

最新評(píng)論

边坝县| 石城县| 兴义市| 嘉义市| 禄丰县| 大石桥市| 阳信县| 监利县| 河南省| 大庆市| 宜丰县| 密山市| 孟连| 麻栗坡县| 临颍县| 延寿县| 静乐县| 从江县| 桑植县| 乌审旗| 平果县| 宝清县| 葵青区| 噶尔县| 闵行区| 金沙县| 城市| 汝南县| 成安县| 临澧县| 长子县| 德令哈市| 商河县| 鲜城| 永丰县| 广汉市| 新竹县| 霍林郭勒市| 岚皋县| 昌吉市| 读书|