当前位置:首页 > 科技  > 软件

一种避免大量If-else代码的新思路

来源: 责编: 时间:2024-04-26 17:34:52 123观看
导读哈喽,各位代码战士们,我是Jensen,一个梦想着和大家一起在代码的海洋里遨游,顺便捡起那些散落的知识点的程序员小伙伴。今天,我要给大家带来一个超级无敌霹雳的编码新招式,只要看完,保证你的代码像用了某某洗发水一样,不仅去屑

zrN28资讯网——每日最新资讯28at.com

哈喽,各位代码战士们,我是Jensen,一个梦想着和大家一起在代码的海洋里遨游,顺便捡起那些散落的知识点的程序员小伙伴。zrN28资讯网——每日最新资讯28at.com

今天,我要给大家带来一个超级无敌霹雳的编码新招式,只要看完,保证你的代码像用了某某洗发水一样,不仅去屑还更柔顺。zrN28资讯网——每日最新资讯28at.com

咱们要聊的是那些让人又爱又恨的技术点:自定义异常、全局异常捕获、断言。zrN28资讯网——每日最新资讯28at.com

一、控制异常流程

首先,让我们来聊聊自定义异常。zrN28资讯网——每日最新资讯28at.com

你知道的,在Java的世界里,我们通常用if-else语句来检查那些让人头疼的条件。zrN28资讯网——每日最新资讯28at.com

比如用户登录:zrN28资讯网——每日最新资讯28at.com

// 伪代码if (验证码 != 8888) {    return "验证码错误";}// 处理其他业务逻辑return "登录成功";

但是,你有没有想过,如果不用if-else,而是用异常来控制流程,会怎样呢?zrN28资讯网——每日最新资讯28at.com

比如,你的登录方法里,验证码不正确,不是返回一个错误信息,而是“砰”地一声抛出个异常。zrN28资讯网——每日最新资讯28at.com

// 伪代码if (验证码 != 8888) {    throw new ServiceException("验证码错误");}// 处理其他业务逻辑return "登录成功";

听起来是不是有点疯狂?但这就是自定义异常的魅力所在,它能让你的代码看起来像是在演电影,每个异常都是一个剧情转折。zrN28资讯网——每日最新资讯28at.com

这里封装了一个业务类异常类ServiceException,该异常类继承了运行时异常RuntimeException:zrN28资讯网——每日最新资讯28at.com

/** * 服务异常,可用于控制业务异常流程,抛出后由统一异常增强类捕获,返回友好提示 * * @author Jensen * @公众号 架构师修行录 */@Datapublic class ServiceException extends RuntimeException {    protected Integer code;    public ServiceException(Integer code, String message) {        super(message);        this.code = code;    }    public ServiceException() {        this(500, "请求成功但是服务异常");    }    public ServiceException(String message) {        this(500, message);    }    public ServiceException(Throwable e) {        this(e.getMessage());    }}

使用自定义异常来代替传统的if-else语句进行错误处理和流程控制,有其优缺点:zrN28资讯网——每日最新资讯28at.com

优点:zrN28资讯网——每日最新资讯28at.com

  • 提高代码可读性:自定义异常可以让你更清晰地表达错误情况,使得代码的意图更容易理解。
  • 集中错误处理:通过抛出和捕获异常,你可以将错误处理逻辑集中到特定的位置,而不是分散在代码的多个地方。
  • 易于维护:当需要修改或扩展错误处理逻辑时,使用异常机制可以更容易地进行维护和升级。
  • 支持多路选择:在某些情况下,异常可以用于实现多路选择结构,通过不同的异常类型来区分不同的执行路径。
  • 资源管理:异常处理机制通常与资源管理(如文件关闭、数据库连接释放等)结合使用,确保资源在使用完毕后得到正确释放。

缺点:zrN28资讯网——每日最新资讯28at.com

  • 性能开销:异常处理通常比条件判断要慢,因为它涉及到栈展开和异常对象的创建。
  • 滥用风险:异常机制有时会被滥用,例如用于正常的流程控制,这可能会导致性能问题和难以理解的代码。
  • 调试困难:异常可能会使调试变得更加困难,特别是在复杂的异常传播和处理过程中。
  • 异常类型管理:随着项目的发展,可能会有大量的自定义异常类型,管理这些异常类型并确保它们的适当使用可能会变得复杂。
  • 语言特性依赖:使用异常处理可能依赖于特定的编程语言特性,这可能会限制代码的移植性。

总的来说,自定义异常在处理错误和异常情况时提供了一种强大而灵活的机制,我觉得可以使用,但不能滥用,常规的还是要使用if-else控制,涉及API的中断流程可以快速跳出内部,并且R对象可无须传递进Service层。zrN28资讯网——每日最新资讯28at.com

二、全局异常捕获

想象一下,你的业务代码里抛出了一大堆异常,你总不能把这些异常原封不动地扔给API的使用者吧。zrN28资讯网——每日最新资讯28at.com

这时候,@RestControllerAdvice就像是那个超级英雄,跳出来拯救世界,把所有的异常都捕获起来,然后优雅地包装成一个个友好的响应。zrN28资讯网——每日最新资讯28at.com

@RestControllerAdvice 是 Spring MVC 中的一个注解,用于定义一个全局的异常处理类,该类可以捕获和处理 Spring 应用中发生的特定类型的异常。这个注解通常与 @ExceptionHandler 注解一起使用,来定义处理特定异常的方法。zrN28资讯网——每日最新资讯28at.com

@RestControllerAdvice 的主要作用和特点包括:zrN28资讯网——每日最新资讯28at.com

  • 全局异常处理:通过在类上使用 @RestControllerAdvice 注解,你可以定义一个类来全局处理控制器(Controller)中抛出的异常。
  • 减少重复代码:你不需要在每个控制器中编写相同的异常处理逻辑。通过定义一个全局的异常处理类,可以统一处理特定类型的异常,从而减少代码重复。
  • 自定义错误响应:可以自定义异常的响应格式,例如返回 JSON 对象,包含错误信息、状态码等,以提供更友好的错误提示给前端。
  • 支持多控制器:一个 @RestControllerAdvice 类可以为多个控制器提供异常处理支持,无论这些控制器是否位于同一个包路径下。
  • 组合使用:可以定义多个 @RestControllerAdvice 类,并通过 basePackages 或 basePackageClasses 属性来指定它们所影响的控制器包路径。
  • 支持继承:如果多个控制器有相似的异常处理需求,可以通过继承一个基础的异常处理类来实现代码复用。

捕获业务异常ServiceException后,封装R对象返回给接口调用方:zrN28资讯网——每日最新资讯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来实现异常流程的控制了,并且方法上注解了@Transactional实现的事务控制,在抛出异常后也是能正常回滚的。zrN28资讯网——每日最新资讯28at.com

三、封装使用业务断言

在Java中,断言就像是那个总是在后台默默支持你的好朋友,它在开发和测试阶段帮你检查那些逻辑错误。zrN28资讯网——每日最新资讯28at.com

但是,别忘了,它也是有脾气的,一旦到了生产环境,它就罢工了。所以,记得在需要的时候启用它,不需要的时候,就让它好好休息。zrN28资讯网——每日最新资讯28at.com

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

断言的特点:zrN28资讯网——每日最新资讯28at.com

  • 条件检查:断言用于检查程序的预期条件,如果条件不满足,则抛出异常。
  • 调试时有用:断言在开发和测试阶段非常有用,可以帮助开发者快速定位问题。
  • 性能考虑:由于断言可能会影响程序性能,因此在生产环境中通常不启用断言。
  • 非正式错误处理:断言不是错误处理的一部分,它不适用于处理那些预期会发生的情况。

使用断言的注意事项:zrN28资讯网——每日最新资讯28at.com

  • 性能影响:断言会增加额外的性能开销,因为每次断言都会计算布尔表达式的值。
  • 生产环境:在生产环境中,断言应该被禁用,以避免不必要的性能损耗。
  • 异常处理:断言抛出的是 AssertionError,这是一种特殊的 Error,通常不应该被应用程序捕获或处理。

断言是Java语言的一个特性,它的使用应该谨慎,主要限于开发和测试阶段,以确保生产环境中的程序性能和稳定性。zrN28资讯网——每日最新资讯28at.com

我们借鉴断言这种设计思想,针对业务异常进一步封装,形成 “业务断言”,主要目标只有一个:zrN28资讯网——每日最新资讯28at.com

管理我们对代码的期望。zrN28资讯网——每日最新资讯28at.com

先定义一个业务断言工具类BizAssert:zrN28资讯网——每日最新资讯28at.com

/** * 业务断言类,断言不通过将抛出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();    }}

使用业务断言:zrN28资讯网——每日最新资讯28at.com

// 从数据库中查询出用户User user = UserQuery.builder().id(userId).build().getOne();// 业务断言,我希望查出来的用户不能为null,否则后续业务会报错BizAssert.notNull(user);// 其他针对user的业务处理逻辑Map<String, String> data = new HashMap<>();data.put("girl-friend", user.getName());

四、写在最后

上述提到的业务断言方法,仅展示了其中一部分,除了简单的判断,我们还可以加上日期比较、数值大小比较、equals比较、集合的contains方法等等,我把它的完整版集成到了我的D3Boot开源基础框架内,大家需要可以移步Gitee抄作业。

Gitee源码地址:zrN28资讯网——每日最新资讯28at.com

https://gitee.com/jensvn/d3boot(例行赊Star)zrN28资讯网——每日最新资讯28at.com

D3boot基础框架具体的使用方式见源码的README.md文件,这里不再赘述。zrN28资讯网——每日最新资讯28at.com

能写一行代码的事,绝不写3行5行,适度封装,让代码更优雅!zrN28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-85874-0.html一种避免大量If-else代码的新思路

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

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

下一篇: 一篇学会SpringBoot的核心内容之自动装配

标签:
  • 热门焦点
  • 俄罗斯:将审查iPhone等外国公司设备 保数据安全

    俄罗斯:将审查iPhone等外国公司设备 保数据安全

    iPhone和特斯拉都属于在各自领域领头羊的品牌,推出的产品也也都是数一数二的,但对于一些国家而言,它们的产品可靠性和安全性还是在限制范围内。近日,俄罗斯联邦通信、信息技术
  • 6月iOS设备好评榜:第一蝉联榜首近一年

    6月iOS设备好评榜:第一蝉联榜首近一年

    作为安兔兔各种榜单里变化最小的那个,2023年6月的iOS好评榜和上个月相比没有任何排名上的变化,仅仅是部分设备好评率的下降,长年累月的用户评价和逐渐退出市场的老款机器让这
  • 三言两语说透设计模式的艺术-简单工厂模式

    三言两语说透设计模式的艺术-简单工厂模式

    一、写在前面工厂模式是最常见的一种创建型设计模式,通常说的工厂模式指的是工厂方法模式,是使用频率最高的工厂模式。简单工厂模式又称为静态工厂方法模式,不属于GoF 23种设计
  • 三万字盘点 Spring 九大核心基础功能

    三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • JVM优化:实战OutOfMemoryError异常

    JVM优化:实战OutOfMemoryError异常

    一、Java堆溢出堆内存中主要存放对象、数组等,只要不断地创建这些对象,并且保证 GC Roots 到对象之间有可达路径来避免垃 圾收集回收机制清除这些对象,当这些对象所占空间超过
  • 零售大模型“干中学”,攀爬数字化珠峰

    零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • 一条抖音4亿人围观 ! 这家MCN比无忧传媒还野

    一条抖音4亿人围观 ! 这家MCN比无忧传媒还野

    作者:Hiu 来源:互联网品牌官01 擦边少女空降热搜,幕后推手曝光被网友誉为&ldquo;纯欲天花板&rdquo;的女网红井川里予,近期因为一组哥特风照片登上热搜,引发了一场互联网世界关于
  • 网传小米汽车开始筛选交付中心 建筑面积不低于3000平方米

    网传小米汽车开始筛选交付中心 建筑面积不低于3000平方米

    7月7日消息,近日有微博网友@长三角行健者爆料称,据经销商集团反馈,小米汽车目前已经开始了交付中心的筛选工作,要求候选场地至少有120个车位,建筑不能低
  • 消息称小米汽车开始筛选交付中心:需至少120个车位

    消息称小米汽车开始筛选交付中心:需至少120个车位

    IT之家 7 月 7 日消息,日前,有微博简介为“汽车行业从业者、长三角一体化拥护者”的微博用户 @长三角行健者 发文表示,据经销商集团反馈,小米汽车目前
Top