如何避免大量的成功失败判断,如何不再纠结发现错误时是否该打印日志

问题描述:编译流程图时,逻辑复杂,嵌套很深,很多函数都有成功失败返回值,造成每层函数都出现大量的成功失败判断,并且不知道打印日志是该在函数外,还是在函数内打印,感觉每次发现失败的时候都应该打印日志,但是又觉得有打印有重复,同时,打印的日志很容易将做什么和失败原因割裂开。这两个问题困扰了我编码很多年了,一直没搞明白为什么会这样。

 

日志解决办法:出现上述问题,实际上是因为我犯了一个致命的错误,就是对发现错误进行了重复处理。因为打印日志实际上是对错误的处理,而返回失败也是对错误的处理,只要避免发生错误重复处理,我们离找到解决办法就只有一步之遥了。

直观现象就是,只要我们的函数有返回错误,则不应该打印日志(即函数如果正确地对错误进行了处理,则函数一定是没返回错误的)。打印日志发生的地方一定是我们能终结错误的地方。按照这个规则,我们的错误应该一层一层的往外返回(不往外返回就会触发错误重复处理),一般情况下,只有返回到系统边界的时候才能正确处理错误,比如界面层这个边界,把错误信息告诉用户(比如打印日志或弹出消息框等),错误才能正常终止。这时,也容易确定用户正在做什么,将做什么和异常中的失败原因结合起来很容易就能打印出友好的日志。有时触发一个事件可能通过工具栏按钮或右键菜单,如果不搞一个控制层直接在界面中处理的话,可能会出现重复代码,所以,有时错误返回到控制层就结束了,界面层仅仅是简单地调用一下控制层而已(设计分层问题,和我们要解决的问题关系不大)。

当然,错误不一定就要返回到边界才能终止,更通用的说法是错误返回到能处理它的地方终止就行,比如打印调试日志的函数出现错误了,只需要把这个错误捕获并忽略掉就行了,因为没有更好的其他方式处理这种错误,就算一直返回出去也没法处理,并且这种错误也无关紧要,所以一般打印调试日志的函数都是没有返回值的。

 

判断解决办法:这涉及到对错误进行处理的两种方式,老式的返回值方式(C语言风格)和新式的抛异常方式(Java风格)。

返回值方式有四大缺点,一是到处都得进行显式判断,并把返回值往外层层传递。二是错误信息不太容易往外传,Win32的最后错误代码方式相当于只能传递错误类型,并不能灵活传递具体的错误信息,不友好。三是返回值用来传递成功失败信息了,正确想返回的东西只能放在参数中,造成函数使用起来复杂不直观。四是没有强迫用户处理错误返回值。

个人觉得,抛异常方式还是比返回值方式先进一些,虽然道理差不多,抛异常方式无非是将返回值放到异常对象中往外传递而已,因为是对象,故通过对象类型就确定了错误类型,而对象中的成员又可以容易携带其他信息,比如具体的错误消息等。

而抛异常方式正好可以解决返回值方式的问题,首先异常会默认往外层传递,不需要程序员显式转手传递,程序员只需要按期望的正常流程处理,发现不正常的时候抛异常就行。其次,错误信息很容易往外传递。其三,函数的返回值可以真正用来返回正常情况下的返回值,使用起来简单直观。最后,抛异常方式强制用户处理错误。

这样看来,别人说尽量用抛异常的方式处理错误还是有道理的。

现在,终于明白了为什么Win32函数基本上都有返回值,因为大部分情况下函数都需要用返回值告诉调用者函数是成功还是失败了。而Java中,函数是成功还是失败一般都通过抛异常来告诉调用者,故相当的函数都没有返回值(不会返回布尔值)。

一般从C/C++系转Java的开发者,思想上很难接受抛异常的错误处理方式,故写出来的java代码仍然习惯于用返回值来告诉调用者结果,这种观念得改,学会适应,至少得入乡随俗

不过采用返回值还是抛异常还是相当有争议的(比如性能),不能说抛异常就没缺点,大家是仁者见仁智者见智。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值