日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

一種避免大量If-else代碼的新思路

來源: 責(zé)編: 時(shí)間:2024-04-26 17:34:52 198觀看
導(dǎo)讀哈嘍,各位代碼戰(zhàn)士們,我是Jensen,一個(gè)夢想著和大家一起在代碼的海洋里遨游,順便撿起那些散落的知識(shí)點(diǎn)的程序員小伙伴。今天,我要給大家?guī)硪粋€(gè)超級(jí)無敵霹靂的編碼新招式,只要看完,保證你的代碼像用了某某洗發(fā)水一樣,不僅去屑

7Rg28資訊網(wǎng)——每日最新資訊28at.com

哈嘍,各位代碼戰(zhàn)士們,我是Jensen,一個(gè)夢想著和大家一起在代碼的海洋里遨游,順便撿起那些散落的知識(shí)點(diǎn)的程序員小伙伴。7Rg28資訊網(wǎng)——每日最新資訊28at.com

今天,我要給大家?guī)硪粋€(gè)超級(jí)無敵霹靂的編碼新招式,只要看完,保證你的代碼像用了某某洗發(fā)水一樣,不僅去屑還更柔順。7Rg28資訊網(wǎng)——每日最新資訊28at.com

咱們要聊的是那些讓人又愛又恨的技術(shù)點(diǎn):自定義異常、全局異常捕獲、斷言。7Rg28資訊網(wǎng)——每日最新資訊28at.com

一、控制異常流程

首先,讓我們來聊聊自定義異常。7Rg28資訊網(wǎng)——每日最新資訊28at.com

你知道的,在Java的世界里,我們通常用if-else語句來檢查那些讓人頭疼的條件。7Rg28資訊網(wǎng)——每日最新資訊28at.com

比如用戶登錄:7Rg28資訊網(wǎng)——每日最新資訊28at.com

// 偽代碼if (驗(yàn)證碼 != 8888) {    return "驗(yàn)證碼錯(cuò)誤";}// 處理其他業(yè)務(wù)邏輯return "登錄成功";

但是,你有沒有想過,如果不用if-else,而是用異常來控制流程,會(huì)怎樣呢?7Rg28資訊網(wǎng)——每日最新資訊28at.com

比如,你的登錄方法里,驗(yàn)證碼不正確,不是返回一個(gè)錯(cuò)誤信息,而是“砰”地一聲拋出個(gè)異常。7Rg28資訊網(wǎng)——每日最新資訊28at.com

// 偽代碼if (驗(yàn)證碼 != 8888) {    throw new ServiceException("驗(yàn)證碼錯(cuò)誤");}// 處理其他業(yè)務(wù)邏輯return "登錄成功";

聽起來是不是有點(diǎn)瘋狂?但這就是自定義異常的魅力所在,它能讓你的代碼看起來像是在演電影,每個(gè)異常都是一個(gè)劇情轉(zhuǎn)折。7Rg28資訊網(wǎng)——每日最新資訊28at.com

這里封裝了一個(gè)業(yè)務(wù)類異常類ServiceException,該異常類繼承了運(yùn)行時(shí)異常RuntimeException:7Rg28資訊網(wǎng)——每日最新資訊28at.com

/** * 服務(wù)異常,可用于控制業(yè)務(wù)異常流程,拋出后由統(tǒng)一異常增強(qiáng)類捕獲,返回友好提示 * * @author Jensen * @公眾號(hào) 架構(gòu)師修行錄 */@Datapublic class ServiceException extends RuntimeException {    protected Integer code;    public ServiceException(Integer code, String message) {        super(message);        this.code = code;    }    public ServiceException() {        this(500, "請求成功但是服務(wù)異常");    }    public ServiceException(String message) {        this(500, message);    }    public ServiceException(Throwable e) {        this(e.getMessage());    }}

使用自定義異常來代替?zhèn)鹘y(tǒng)的if-else語句進(jìn)行錯(cuò)誤處理和流程控制,有其優(yōu)缺點(diǎn):7Rg28資訊網(wǎng)——每日最新資訊28at.com

優(yōu)點(diǎn):7Rg28資訊網(wǎng)——每日最新資訊28at.com

  • 提高代碼可讀性:自定義異常可以讓你更清晰地表達(dá)錯(cuò)誤情況,使得代碼的意圖更容易理解。
  • 集中錯(cuò)誤處理:通過拋出和捕獲異常,你可以將錯(cuò)誤處理邏輯集中到特定的位置,而不是分散在代碼的多個(gè)地方。
  • 易于維護(hù):當(dāng)需要修改或擴(kuò)展錯(cuò)誤處理邏輯時(shí),使用異常機(jī)制可以更容易地進(jìn)行維護(hù)和升級(jí)。
  • 支持多路選擇:在某些情況下,異常可以用于實(shí)現(xiàn)多路選擇結(jié)構(gòu),通過不同的異常類型來區(qū)分不同的執(zhí)行路徑。
  • 資源管理:異常處理機(jī)制通常與資源管理(如文件關(guān)閉、數(shù)據(jù)庫連接釋放等)結(jié)合使用,確保資源在使用完畢后得到正確釋放。

缺點(diǎn):7Rg28資訊網(wǎng)——每日最新資訊28at.com

  • 性能開銷:異常處理通常比條件判斷要慢,因?yàn)樗婕暗綏U归_和異常對(duì)象的創(chuàng)建。
  • 濫用風(fēng)險(xiǎn):異常機(jī)制有時(shí)會(huì)被濫用,例如用于正常的流程控制,這可能會(huì)導(dǎo)致性能問題和難以理解的代碼。
  • 調(diào)試?yán)щy:異常可能會(huì)使調(diào)試變得更加困難,特別是在復(fù)雜的異常傳播和處理過程中。
  • 異常類型管理:隨著項(xiàng)目的發(fā)展,可能會(huì)有大量的自定義異常類型,管理這些異常類型并確保它們的適當(dāng)使用可能會(huì)變得復(fù)雜。
  • 語言特性依賴:使用異常處理可能依賴于特定的編程語言特性,這可能會(huì)限制代碼的移植性。

總的來說,自定義異常在處理錯(cuò)誤和異常情況時(shí)提供了一種強(qiáng)大而靈活的機(jī)制,我覺得可以使用,但不能濫用,常規(guī)的還是要使用if-else控制,涉及API的中斷流程可以快速跳出內(nèi)部,并且R對(duì)象可無須傳遞進(jìn)Service層。7Rg28資訊網(wǎng)——每日最新資訊28at.com

二、全局異常捕獲

想象一下,你的業(yè)務(wù)代碼里拋出了一大堆異常,你總不能把這些異常原封不動(dòng)地扔給API的使用者吧。7Rg28資訊網(wǎng)——每日最新資訊28at.com

這時(shí)候,@RestControllerAdvice就像是那個(gè)超級(jí)英雄,跳出來拯救世界,把所有的異常都捕獲起來,然后優(yōu)雅地包裝成一個(gè)個(gè)友好的響應(yīng)。7Rg28資訊網(wǎng)——每日最新資訊28at.com

@RestControllerAdvice 是 Spring MVC 中的一個(gè)注解,用于定義一個(gè)全局的異常處理類,該類可以捕獲和處理 Spring 應(yīng)用中發(fā)生的特定類型的異常。這個(gè)注解通常與 @ExceptionHandler 注解一起使用,來定義處理特定異常的方法。7Rg28資訊網(wǎng)——每日最新資訊28at.com

@RestControllerAdvice 的主要作用和特點(diǎn)包括:7Rg28資訊網(wǎng)——每日最新資訊28at.com

  • 全局異常處理:通過在類上使用 @RestControllerAdvice 注解,你可以定義一個(gè)類來全局處理控制器(Controller)中拋出的異常。
  • 減少重復(fù)代碼:你不需要在每個(gè)控制器中編寫相同的異常處理邏輯。通過定義一個(gè)全局的異常處理類,可以統(tǒng)一處理特定類型的異常,從而減少代碼重復(fù)。
  • 自定義錯(cuò)誤響應(yīng):可以自定義異常的響應(yīng)格式,例如返回 JSON 對(duì)象,包含錯(cuò)誤信息、狀態(tài)碼等,以提供更友好的錯(cuò)誤提示給前端。
  • 支持多控制器:一個(gè) @RestControllerAdvice 類可以為多個(gè)控制器提供異常處理支持,無論這些控制器是否位于同一個(gè)包路徑下。
  • 組合使用:可以定義多個(gè) @RestControllerAdvice 類,并通過 basePackages 或 basePackageClasses 屬性來指定它們所影響的控制器包路徑。
  • 支持繼承:如果多個(gè)控制器有相似的異常處理需求,可以通過繼承一個(gè)基礎(chǔ)的異常處理類來實(shí)現(xiàn)代碼復(fù)用。

捕獲業(yè)務(wù)異常ServiceException后,封裝R對(duì)象返回給接口調(diào)用方:7Rg28資訊網(wǎng)——每日最新資訊28at.com

@RestControllerAdvicepublic class GlobalRestExceptionAdvice {    @ExceptionHandler({ServiceException.class})    public R<Map<String, String>> serviceException(HttpServletRequest request, ServiceException e) {        return R.fail(e.getCode(), e.getMessage(), null);    }}

到這里,我們就可以通過拋出ServiceException來實(shí)現(xiàn)異常流程的控制了,并且方法上注解了@Transactional實(shí)現(xiàn)的事務(wù)控制,在拋出異常后也是能正常回滾的。7Rg28資訊網(wǎng)——每日最新資訊28at.com

三、封裝使用業(yè)務(wù)斷言

在Java中,斷言就像是那個(gè)總是在后臺(tái)默默支持你的好朋友,它在開發(fā)和測試階段幫你檢查那些邏輯錯(cuò)誤。7Rg28資訊網(wǎng)——每日最新資訊28at.com

但是,別忘了,它也是有脾氣的,一旦到了生產(chǎn)環(huán)境,它就罷工了。所以,記得在需要的時(shí)候啟用它,不需要的時(shí)候,就讓它好好休息。7Rg28資訊網(wǎng)——每日最新資訊28at.com

assert condition : "This is an error message.";

斷言的特點(diǎn):7Rg28資訊網(wǎng)——每日最新資訊28at.com

  • 條件檢查:斷言用于檢查程序的預(yù)期條件,如果條件不滿足,則拋出異常。
  • 調(diào)試時(shí)有用:斷言在開發(fā)和測試階段非常有用,可以幫助開發(fā)者快速定位問題。
  • 性能考慮:由于斷言可能會(huì)影響程序性能,因此在生產(chǎn)環(huán)境中通常不啟用斷言。
  • 非正式錯(cuò)誤處理:斷言不是錯(cuò)誤處理的一部分,它不適用于處理那些預(yù)期會(huì)發(fā)生的情況。

使用斷言的注意事項(xiàng):7Rg28資訊網(wǎng)——每日最新資訊28at.com

  • 性能影響:斷言會(huì)增加額外的性能開銷,因?yàn)槊看螖嘌远紩?huì)計(jì)算布爾表達(dá)式的值。
  • 生產(chǎn)環(huán)境:在生產(chǎn)環(huán)境中,斷言應(yīng)該被禁用,以避免不必要的性能損耗。
  • 異常處理:斷言拋出的是 AssertionError,這是一種特殊的 Error,通常不應(yīng)該被應(yīng)用程序捕獲或處理。

斷言是Java語言的一個(gè)特性,它的使用應(yīng)該謹(jǐn)慎,主要限于開發(fā)和測試階段,以確保生產(chǎn)環(huán)境中的程序性能和穩(wěn)定性。7Rg28資訊網(wǎng)——每日最新資訊28at.com

我們借鑒斷言這種設(shè)計(jì)思想,針對(duì)業(yè)務(wù)異常進(jìn)一步封裝,形成 “業(yè)務(wù)斷言”,主要目標(biāo)只有一個(gè):7Rg28資訊網(wǎng)——每日最新資訊28at.com

管理我們對(duì)代碼的期望。7Rg28資訊網(wǎng)——每日最新資訊28at.com

先定義一個(gè)業(yè)務(wù)斷言工具類BizAssert:7Rg28資訊網(wǎng)——每日最新資訊28at.com

/** * 業(yè)務(wù)斷言類,斷言不通過將拋出ServiceException */@UtilityClasspublic class BizAssert {      public <T> T notNull(T dontNull) {        if (dontNull == null) {            throw new ServiceException("this object must not be null");        }        return dontNull;    }    public void notBlank(String dontBlank) {        if (dontBlank == null || dontBlank.length() == 0) {            throw new ServiceException("this string must not be null or blank");        }    }    public <E, T extends Iterable<E>> T notEmpty(T dontEmpty) {        if (dontEmpty == null || !dontEmpty.iterator().hasNext()) {            throw new ServiceException("this collection must not be null or empty");        }        return dontEmpty;    }    public <T> T isOk(IR r) {        if (r == null || !r.isOk()) {            throw new ServiceException(r == null ? "this result must not be null" : r.getMsg());        }        return r.getData();    }    public <T> T notNull(IR r) {        if (r == null || !r.isOk() || r.getData() == null) {            throw new ServiceException(r == null ? "this result must not be null" : r.getMsg());        }        return r.getData();    }}

使用業(yè)務(wù)斷言:7Rg28資訊網(wǎng)——每日最新資訊28at.com

// 從數(shù)據(jù)庫中查詢出用戶User user = UserQuery.builder().id(userId).build().getOne();// 業(yè)務(wù)斷言,我希望查出來的用戶不能為null,否則后續(xù)業(yè)務(wù)會(huì)報(bào)錯(cuò)BizAssert.notNull(user);// 其他針對(duì)user的業(yè)務(wù)處理邏輯Map<String, String> data = new HashMap<>();data.put("girl-friend", user.getName());

四、寫在最后

上述提到的業(yè)務(wù)斷言方法,僅展示了其中一部分,除了簡單的判斷,我們還可以加上日期比較、數(shù)值大小比較、equals比較、集合的contains方法等等,我把它的完整版集成到了我的D3Boot開源基礎(chǔ)框架內(nèi),大家需要可以移步Gitee抄作業(yè)。

Gitee源碼地址:7Rg28資訊網(wǎng)——每日最新資訊28at.com

https://gitee.com/jensvn/d3boot(例行賒Star)7Rg28資訊網(wǎng)——每日最新資訊28at.com

D3boot基礎(chǔ)框架具體的使用方式見源碼的README.md文件,這里不再贅述。7Rg28資訊網(wǎng)——每日最新資訊28at.com

能寫一行代碼的事,絕不寫3行5行,適度封裝,讓代碼更優(yōu)雅!7Rg28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-85874-0.html一種避免大量If-else代碼的新思路

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: Node.js 重大更新,你知道更新了啥?

下一篇: 一篇學(xué)會(huì)SpringBoot的核心內(nèi)容之自動(dòng)裝配

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 天水市| 喀喇沁旗| 嵩明县| 年辖:市辖区| 左权县| 阿巴嘎旗| 山西省| 台山市| 鸡东县| 卓尼县| 阿克陶县| 从江县| 铁岭县| 丰城市| 利津县| 盐池县| 望江县| 尉犁县| 伊吾县| 禹州市| 敦化市| 宜兴市| 左权县| 元江| 神农架林区| 常宁市| 龙江县| 阜阳市| 庆阳市| 德化县| 邓州市| 竹山县| 温泉县| 丰镇市| 清涧县| 永平县| 鹤庆县| 会宁县| 文水县| 金华市| 晴隆县|