首页 > 技术文章 > 小课堂Week8 例外处理设计的逆袭Part1

dt-zhw 2016-08-20 13:09 原文

小课堂Week8

例外处理设计的逆袭Part1

今天和大家讲一本书,书名是《例外处理设计的逆袭》。
为什么想讲这本书,是因为,例外处理在程序代码中到处存在,但是这些到底该如何写好,总觉得有些懵懵懂懂。正好听到Jackson老师的推荐,读到了这本书,如获甘霖,好东西和大家分享。

什么是例外处理

这本书的作者是一位台湾的大牛叫Teddy Chen。台版和港版的书有一个比较好的习惯,就是对于英文的技术词汇,解释但不翻译,因为中文和英文在某些词汇的描述上强度是不同的,直译往往会丢失一部分的含义,所以先来界定几个词汇。

  • Exception:这个就是书名中指的例外,我们一般也可以称其为异常。
  • Fault、Error、Failure:
    这三个词是exception的三个生命周期:
    fault指的系统的缺陷,是一种内在的东西,比如bug。
    error指的的一种表现出来的错误状态,比如异常的提示,fault是error发生的原因。
    failure指的是系统服务的异常,比如宕机,会产生业务影响。

为什么要理清这三个概念呢,结合下工作:
作为程序员,我们收到的往往都是failure的信息,而要解决问题,我们往往需要打交道的是fault,大家发现了没有,这个中间是一段空白地带的,而这个就是例外处理研究的方向。

所以,我们所谈的例外处理,指的是:

  1. 如何通过failure,快速找到fault。
  2. 更进一步,在发生fault的情况下,如何避免不发生failure。

fault的分类

我们先从fault开始,根据美国一些大神的研究,fault依据产生原因,可以区分为两个类:

  • design fault
    一般我们称为bug,这是人为造成的问题,如果不修改代码,不会自动消失。
    有一个观点很重要,就是我们会认为,design fault是一种不可预测的错误。原因是这样的,这个就有点像我们做考卷,其实每个人都是向着做对的方向来做的,但事实上,里面会有很多的错误,这个站在做题者的角度是无法预知的,和知识水平有关,因为能预知的话,他就不会做错。所以,对于那种故意做错题的情况,请大家不要犯,这个也不在我们讨论范围内。

  • component fault
    由于环境影响或者其他客观因素造成的问题,比如内存溢出。这种问题,有可能是暂时的、甚至是偶发的。有一个重要的观点是,我们认为,这种问题是可预测的。

在Java中,就将异常分为了两类,CheckedException和UnCheckedException。
其中,CheckedException在语法层面会强制要求处理,比如SQLException、IOException等。
UnCheckedException在语法层面不会强制要求处理,比如各种RunTimeException。
这个是符合对两种fault定义的,CheckedException用来处理component fault,UnCheckedException用来处理design fault。

try-catch-finally的职责分担

Try-catch-finally是我们通常用来进行例外处理的语法结构。这个说明下三个模块的定位。

  • Try
    在try模块中,会对逻辑进行执行,所以在try模块中,最重要的职责是识别并报出Error。

  • Catch
    因为所有的例外都会集中到Catch模块中处理,Catch的职责主要有两点:

  1. 处理Error,可以采用回滚、重试等方式,直接把Error消灭掉。
  2. 如果无法处理,则上报给上级模块来进行处理。
  • Finnaly
    这是Java等语言中提供的辅助性语法结构,可以比较方便的解决资源回收清理的问题。这个和例外处理是无关的。
    进行资源回收清理时,也是有可能出现异常,但是,对于Java语言来说,一个程序一次只能抛出一个异常,回收的异常会覆盖掉try逻辑中的异常,而且这个是默认的逻辑!!!
    所以,在这里,推荐采用两害相权取其轻的原则,将清理异常屏蔽掉,优先将try逻辑中的异常给抛出来。另外,也可以使用Supressed Exception,将异常进行组装后抛出。

小结

今天主要都是在提出问题,目标是明确关注点,在后续会继续深入一些具体的问题,介绍下书中提出的实践和方法。

推荐阅读