异常大讨论-抛出异常还是返回false
iteye精华帖之异常大讨论
原帖链接http://www.iteye.com/topic/2038
Robbin的观点
观点1:Exception实际上代表了一个UseCase中的异常流的处理。
绝大多数的Java程序员根本就没有领悟“Exception”的真正用处。他们就是把Exception当做异常来理解,没有明白Exception实际上代表了一个UseCase中的异常流的处理。
在使用UseCase来描述一个场景的时候,有一个主事件流和n个异常流。异常流可能发生在主事件流的过程,而try语句里面实现的是主事件流,而catch里面实现的是异常流,在这里Exception不代表程序出现了异常或者错误,Exception只是面向对象化的业务逻辑控制方法。如果没有明白这一点,那么我认为并没有真正明白应该怎么使用Java来正确的编程。
而我自己写的程序,会自定义大量的Exception类,所有这些Exception类都不意味着程序出现了异常或者错误,只是代表非主事件流的发生的,用来进行那些分支流程的流程控制的。例如你往权限系统中增加一个用户,应该定义1个异常类,UserExistedException,抛出这个异常不代表你插入动作失败,只说明你碰到一个分支流程,留待后面的catch中来处理这个分支流程。传统的程序员会写一个if else来处理,而一个合格的OOP程序员应该有意识的使用try catch 方式来区分主事件流和n个分支流程的处理,通过try catch,而不是if else来从代码上把不同的事件流隔离开来进行分别的代码撰写。
观点2:用boolean做返回值判断方法是否执行成功是错误的
另外纠正一个错误的观点:很多人喜欢定义方法的返回类型为boolean型的,当方法正确执行,没有出错的时候返回true,而方法出现出现了问题,返回false。这在Java编程当中是大错而特错的!
方法的返回值只意味着当你的方法调用要返回业务逻辑的处理结果的。如果业务逻辑不带处理结果,那么就是void的,不要使用返回值boolean来代表方法是否正确执行。
例如 用户登陆方法
(注:Robbins认为错误的写法:)
- boolean login(String username, String password);;
很多人喜欢用boolean返回,如果是true,就是login了,如果false就是没有登陆上。其实是错误的。还有的人定义返回值为int型的,例如如果正确返回就是0,如果用户找不到就是-1,如果密码不对,就是-2
- int login(String username, String password);;
然后在主程序里面写一个if else来判断不同的流程。
- int logon = UserManager.login(xx,xx);;
- if (logon ==0); {
- ...
- } else if (logon == 1); {
- ...
- } else if (logon ==2); {
- ..}
这是面向过程的编程逻辑,不是面向对象的编程逻辑。
(注:Robbins认为正确的写法:)
- User login(String username, String password); throws UserNotFoundException, PasswordNotMatchException;
主程序这样来写:
- try {
- UserManager.login(xx,xx);;
- ....
- 用户登陆以后的主事件流代码
- } catch (UserNotFoundException e); {
- ...
- 用户名称没有的事件处理,例如产生一个提示用户注册的页面
- } catch (PasswordNotMatchException e); {
- ....
- 密码不对的事件处理,例如forward到重新登陆的页面
- }
观点3:用分层与返回值的角度看异常
什么叫做程序抛出的异常,什么叫做系统抛出的异常,你能明确界定吗?FileNotFoundException你说算是系统异常呢?还是程序异常?站在某些程序员的角度,他会觉得是系统异常,不过像我喜欢看JDK源代码的人来说,我对Sun的程序什么情况下抛出FileNotFoundException很清楚,这些代码对我来说,和我自己写的代码能有什么不同吗?对我来说,FileNotFoundException就是程序异常。既然JDK可以抛出异常,凭什么我就不能抛出异常?
站在底层程序员的角度来看,根本没有什么系统异常可言,否则的话,还不如不要定义任何异常得了,干脆就是函数调用返回值,你说为什么Sun不定义0,1,2这样的返回值,而是抛出异常呢?Java程序无非就是一堆class,JDK的class可以抛异常,我写的class为什么不能抛出?
异常不异常的界定取决于你所关注的软件层面,例如你是应用软件开发人员,你关心的是业务流程,那么你就应该捕获底层异常,就应该定义业务层异常,向上抛出业务层异常。如果是底层程序员,你就应该定义和抛出底层异常。要不要抛出异常和抛出什么异常取决你站在什么软件层面了,离开这个前提,空谈异常不异常是没有意义的。
观点4:使用异常可以提高程序可读性
举个简单的例子 一个权限判断的方法
boolean checkUserPermission(User user, int mId) throws NoExistUserException, NoExistModuleException {
}
我并不能保证有谁会使用这个权限判断的方法,但按照面向对象的理论,程序中最好只有一个实现相同功能的方法,所以我定义了不存在用户和不存在模块的异常,这样不管是程序组中谁使用这个方法,就可以清楚的知道这个方法实现的功能,也可以知道出错了是因为什么原因出错也就可以采取相应的方法去处理 。
异常大讨论-抛出异常还是返回false的更多相关文章
- null值与非null只比较大小时,只会返回false
DateTime? time=null; DateTime now=DateTime.Now; null值与非null只比较大小时,只会返回false 无论是大于比较还是小于比较还是等于,都会返回fa ...
- 编写高质量代码改善C#程序的157个建议——建议58:用抛出异常代替返回错误代码
建议58:用抛出异常代替返回错误代码 CLR异常机制的优点: 正常控制流会被立即中止,无效值或状态不会在系统中继续传播. 提供了统一的处理错误的方法. 提供了在构造函数.操作符重载及属性中报告异常的遍 ...
- [转载] 在java中为什么变量1000 = 1000 返回false,但是100=100返回true?
ps:题目的意思是指定义相同内容的不同变量之间的==比较.如果直接比较(100 == 100)的结果是true. 运行以下代码: Integer a = 1000, b = 1000; System. ...
- IIS目录下文件共享后System.IO.File.Exists返回false
场景:在iis目录下,因为特殊需要共享一个文件夹,给到其他的技术人员访问,突然发现小小的操作,搞“大”了,使用 string path = Server.MapPath("~/file/te ...
- 横瓜执导众程序员开展大讨论关于C、JAVA及其它主流IT技术使用情况和优点缺点。
横瓜执导众程序员开展大讨论关于C.JAVA及其它主流IT技术使用情况和优点缺点. 遥执乾坤(44758121) 18:21:23 mysql据说只能使用一个索引,我这里几乎所有字段都有索引. 但每个 ...
- preparedstatement execute()操作成功!但是返回false
转自http://blog.sina.com.cn/s/blog_963fb3af01013rcs.html Connection con = getConn(); String sql2 = &qu ...
- yii2 设置的缓存无效,返回false,不存在
为了那些因为标题点进来的小伙伴,我直接把问题解决方案写在开头: 问题描述, $cache->add($key,'value',1800);这样设置了值后,后面无论怎么取这个$key,取出来的结果 ...
- FtpClient.storeFile返回false解决方法
在确定路径和文件名没有中文的情况下添加以下代码 ftp.setFileTransferMode(ftp.BINARY_FILE_TYPE); ftp.enterLocalPassiveMode();/ ...
- Process32First 返回FALSE的原因
一般情况下是不会返回FALSE的,如果发生了,请检查: 1:系统为UNICODE的,一定要设置PROCESSENTRY32的dwSize为sizeof(PROCESSENTRY32)即可..
随机推荐
- Flask(4)- URL 组成部分详解
URL Uniform Resource Locator 的简写,中文名叫统一资源定位符 用于表示服务端的各种资源,例如网页 下面将讲解 Flask 中如何提取组成 URL 的各个部分 URL 组 ...
- 基于Ubuntu18.04一站式部署(python-mysql-redis-nginx)
基于Ubuntu18.04一站式部署 Python3.6.8的安装 1. 安装依赖 ~$ sudo apt install openssl* zlib* 2. 安装python3.6.8(个人建议从官 ...
- MacOS开启PPTP协议
开启PPTP协议: Mac OS X 系统默认开启了完整性保护(System Intregrity Protection,SIP),所以即使是root帐户也无法修改系统目录中的文件.如果需要修改受 ...
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
- [Navicat15 试用期过期解决办法]
Navicat15 试用期过期解决办法 第一步:关闭Navicat 第二步: 打开注册表编辑器,win + R, 输入regedit 第三步: 在最上方搜索框输入HKEY_CURRENT_USER\S ...
- 如何点击穿透Electron不规则窗体的透明区域
实现一个不规则窗体 这里我们实现一个圆形窗体,实现其他形状的窗体与这个方法类似. 首先,把窗口的高度(height)和宽度(width)值修改为相同的值,使窗口成为一个正方形. 其次,把窗口的透明属性 ...
- 我爬取交通学博士付费的GIS资源,每年被动收入2w很简单?
目录 1.背景介绍 2.技术路线 3.数据结果 4.数据分析 5.总结 6.后记 1.背景介绍 某周末闲来无事,顺手打开了CSDN,看到了一个人发布的收费GIS资源,售价是¥19.9,POI数据也有人 ...
- PHP中的MySQLi扩展学习(一)MySQLi介绍
关于 PDO 的学习我们告一段落,从这篇文章开始,我们继续学习另外一个 MySQL 扩展,也就是除了 PDO 之外的最核心的 MySQLi 扩展.可以说它的祖先,也就是 MySQL(原始) 扩展是我们 ...
- mysql数据库备份参数
我用来实现自动全备份的脚本(可以满足一般有前后版本兼容要求的导出导入操作,我的字符集是latin1): mysqldump.exe -umyusername -pmypass -h localhost ...
- 微信公众号jssdk分享接口onMenuShareAppMessage自定义的参数无效,微信分享失败原因
使用jssdk为jweixin-1.4.0.js updateTimelineShareData,安全域名接口也设置正确,可就是分享,转发朋友圈不成功. 解决方案:采用<script src=& ...