点击上方“方志朋”,选择“设为星标”

回复”666“获取新整理的面试文章

作者:myfor

www.cnblogs.com/myfor/p/13024120.html

一个奇怪的用法

我遇到过一个项目,使用 .net core 搭建的一套OA系统,搭建这个系统的架构师,选择将不合法的请求,或是失败的请求用 throw 抛出异常,然后再异常过滤器中打包成一个正常相应的数据,返回给前端。

例:服务器接受到客户端的请求,检查上传的参数的时候,发现少了一个参数,这个时候应该告诉客户端:你少给我了一个参数。在这个系统中,要求所有的工程师遇到这个种情况要抛出异常,并在异常信息里写明要返回给客户端的描述信息。就是:

if (参数少了一个)
{throw new Exception("前端你的参数少了一个");
}

然后在异常过滤器中将异常信息包装成一个正常返回值,主动抛出的异常描述信息也在这个返回值中返回给前端。

现在请思考下这种设计有没有什么不妥?

这种方式完全违背了异常机制的初衷,将异常机制大材小用,而唯一的好处就是写起来短。

异常机制表示这不是一个正常的业务代码,怎么理解?异常的抛出会停止系统的所有接下来的操作,这是强制性的。为什么这么做?为什么要停下来?是因为抛出异常代表发生了一个不可预知的危险操作,代表发生了正常业务逻辑以外的事,如果继续执行下去,可能会发生无法挽回的危险。所以需要一个抛出的操作强制终止程序的执行。

扩展:一百期Java面试题汇总

写个除法器

举个简单的例子,你需要写一个方法来计算两个数相除的商,你可以很快地写下这个方法:

double Div(double n1, double n2)
{return n1 / n2;
}

那如果除数 n2 接收到的是 0 ,怎么办?

在 .net 里除数为 0 的话会直接抛出异常,但如果让你来实现除法的话,你要这么应对这种情况呢?

可能有人会想到,多返回两个结果参数,一个用来指示计算是否成功,一个指示失败的原因,一共有三个参数,就像:

(bool, string, double) Div(double n1, double n2)
{//
}

这个可能是一个比较周全的方法,考虑到成功和失败的情况,但请思考一下,如果除数传进来是 0 ,这个方法会返回 (false, "除数不能为零", ??)。商的返回值应该是什么?有人会想:商的返回值是什么都可以,因为已经有 false 指示相除失败,也有说明失败原因的结果参数了。调用方只要先判断相除是否成功的参数就可以了。

没错,理想情况的确是这样,那么,你要怎么保证调用方一定会按照你的想法去使用这个方法呢?这个时候可能有人会想:那我管不着!别人要乱用我有什么办法!

对,这么想当然没问题,但我们是软件工程师,我们可以做的更好。你想一下,如果你的这个方法被使用在金融系统中,可能会造成多大的损失。无论你的返回值多么详尽,这仍然是一个不安全的方法。在调用方传递了一个不合法的值 0 后,仍然在商的结果位给了一个数字,而你是没有办法保证调用方不会拿你的返回的错误结果商去当作正常的值使用,这可能会在金融系统中造成无法估量的损失,比如算少了你的工资。

这个时候我们应该怎么做,才能帮用户最大程度上减少损失?

抛出异常的妙用

我们要么确保一定给调用方返回一个正确的值,要么在计算不出正确的值时,什么都不返回。这就是需要抛出异常机制的时候了。

在接受到 0 作为除数时,直接抛出错误,阻止程序继续往下走。这样,在调用方给你一个错误的参数,你就阻止了调用方可能会做的胡搞瞎搞,从而迫使调用方检查他的参数。

尽管异常会造成一些性能损耗,但和可能发生的业务损失相比,这些性能损耗太微不足道了。

明白了吗,抛出异常的使用,不是作为正常的业务流程所使用,而是当发生你无法预计的不正常业务流程时,阻止他继续可能会造成的损失来使用的。像开头我提到了架构师搭建的项目,将抛出作为正常业务流程的一部分来使用,这使得抛出这个动作发生得十分频繁。因为你检查客户端的参数,这是一个正常的流程,你能知道哪些参数是正确的,哪些是不正确的,并知道要怎么提醒客户端。如果这里再检查参数不正确后就主动抛出,因为可能发生得十分频繁,就会十分损耗性能。这是十分不可取的一种方式。

思考到这里,想一下,如果你调用的别人的代码抛出了异常,你要怎么办呢?是 try catch 捕获之后,当无事发生吗?这就浪费了别人抛出的一番苦心了,你要做的是,检查修改你的代码,看看参数是不是不正确,完善逻辑,以保证不会再诱发下一次同样的报错。如果你不能保证,并且也不能承担 try catch 后可能会发生的损失,那就让它报错。

热门内容:Spring Boot 还能“内存泄露”?排它!
学会 IDEA REST Client后,postman就可以丢掉了...
为什么老外不愿意用 MyBatis?微服务海量日志怎么处理,推荐你试试这款工具....
HTTP/3 来了 !HTTP/2 还没怎么用起来呢,先一起扫个盲吧!给 Spring Boot 项目减减肥!18.18M 到 0.18M 是如何做到的?
为什么像王者荣耀这样的游戏 Server 不愿意使用微服务?最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ♡

请不要将抛出异常作为业务逻辑使用!!!相关推荐

  1. 业务逻辑应该在哪里实现更为合理呢?

    请大牛们讨论下业务逻辑应该在哪实现较为合理 1.java业务逻辑层. 2.后台存储过程. 因为本人一直都在业务逻辑层实现.但新项目中领导要求将业务写到后台存储过程,java业务逻辑层不承载业务逻辑的实 ...

  2. 抱歉,请不要把 “业务逻辑层” 理解为 “业务中台”

    这是头哥侃码的第197篇原创 在IAS2019中台架构峰会上,我曾与一位年轻帅气的技术小伙来了一番有趣的对话. 因为和朋友有约,所以我在现场互动结束之后,就急匆匆地跟其他嘉宾打了声招呼,抱着笔记本冲出 ...

  3. 高内聚低耦合通俗理解_抱歉,请不要把“业务逻辑层”理解为“业务中台”

    在IAS2019中台架构峰会上,我曾与一位年轻帅气的技术小伙来了一番有趣的对话. 因为和朋友有约,所以我在现场互动结束之后,就急匆匆地跟其他嘉宾打了声招呼,抱着笔记本冲出了会场. 但没想到刚到电梯口, ...

  4. 谷粒商城业务逻辑(一)

    谷粒商城项目业务逻辑 基础篇 后台管理用人人开源三件套 后台管理vue只配置总的请求路由,从网关调用,其它服务只需要注册到网关就可以, renren逆行生成的vue中给label标签赋值,在数据表格中 ...

  5. LINQ : 如何为LINQ TO SQL实现自定义业务逻辑

    LINQ TO SQL很好很强大,它几乎包含了我们能够想到的所有与数据库有关的操作,甚至也包含了一些我们可能都没有想到的. 但不管怎样,也许我们需要在LINQ TO SQL的操作中添加一个自定义业务逻 ...

  6. abp angular 和mvc_使用.net core ABP和Angular模板构建博客管理系统(实现自己的业务逻辑)...

    返回目录 之前写到使用.net core ABP 和Angular模板构建项目,创建后端服务.文章地址:http://www.jianshu.com/p/fde1ea20331f 创建完成后的api基 ...

  7. 【C 语言】字符串拷贝 ( 字符串拷贝业务逻辑代码 | 分离 主函数 与 字符串拷贝 业务模型 )

    文章目录 一.字符串拷贝业务逻辑代码 二.分离 主函数 与 字符串拷贝 业务模型 一.字符串拷贝业务逻辑代码 下面的代码 , 是 字符串 拷贝 最简单的代码 , 仅 使用 指针 遍历内存 , 实现了字 ...

  8. m5310模组数据上传至onenet_硬核干货!基于M5310-A的NB-IoT水表通信模块软件业务逻辑分享...

    根据不同的应用场景需求,目前NB-IoT水表主要有以下几种方案: 图1 几种常见NB水表方案 接下来将从NB-IoT水表上电开机.模组初始化.入网判断.业务逻辑四个环节来详细讲述,以下业务流程仅供参考 ...

  9. 使用 Drools 规则引擎实现业务逻辑,可调试drl文件

    http://www.srcsky.com/tech/arts/389.html 代码下载http://download.csdn.net/detail/zhy011525/2462313 使用 Dr ...

最新文章

  1. 028_自己实现一个LinkedList
  2. TWaver HTML5 + Node.js + express + socket.io + redis(六)
  3. Ruby. Vs . Python
  4. 动手Lab|利用CSI和Kubernetes实现动态扩容
  5. python lxml解析html,当使用lxml.html解析html时,等同于InnerHTML
  6. 曾逼马云道歉,扬言5年超过阿里!3年后市值差了3万亿 !
  7. [原创]错误提示:disagrees about version of symbol module_layout,解决方法
  8. 如何看懂wsdl文件
  9. 深度学习:知识回收(神经网络模型:BPNN原理)
  10. 数据分析常见的英文缩写(一)
  11. MySQL 的 Buffer Pool,终于被我搞懂了
  12. Django计算机毕业设计交通违章举报平台(程序+lw)Python
  13. 软件开发人员 梦想最大的阻碍:毒、赌、黄
  14. 【文智背后的奥秘】系列篇——情感分类
  15. 蛋白质二级结构预测Linux,蛋白质稳定性预测工具-Rosetta ddg_monomer
  16. 命名空间又称名字空间,英文名:Namespace
  17. word 表格不跨行断页
  18. w指令中的IDLE是什么意思
  19. Properties 文件中字符串加了引号
  20. LoRa开发与应用之路八

热门文章

  1. java下输出中文的一点研究
  2. angular轮播图
  3. 虚拟机ubuntu14.04系统设置静态ip
  4. 【bzoj3150】 cqoi2013—新Nim游戏
  5. codevs1137 计算系数
  6. lightoj 1014
  7. [分享]C# 获取Outlook帐号和密码
  8. 技术图文:如何在Python中定义二维数组?
  9. 目前常用的服务器端网络操作系统有,目前常用的服务器端网络操作系统是()。...
  10. Arm 通过虚拟硬件与新的解决方案导向的产品 带动物联网经济转型