程序健壮性: 正常、错误和异常

 

      准确而细致的错误处理是确保程序健壮性的重要关卡。                           ---------   引


       很容易分清正常和错误的区别,但不容易分辨错误和异常的区别。 事实上,从事情概率上可以很容易地分辨。 无论是正常、错误或异常,都是事情发生的一种可能,只是通常正常情形发生的概率更多,错误次之,异常很小。 但小概率事件也会发生。

       举例来说,写一个与天气有关的程序。 天气有晴天、阴天、雨天、雪天,偶尔会有酸雨天,还有既晴又雨的时候。 晴天、阴天和雨天、雪天都可以看成正常情况, 但酸雨天就是一种错误情形,因为是不期望的;既晴且雨的天气就更少发生了,可以看作一种异常,是人们未曾预料到的。 想想最初的那个BUG, 据说是飞虫卡在机器里了, 这是一种预料之外的事件,可称为异常。 而预料之内的事情,可以包括正常和错误。


       总结一下: 正常和错误都属于预料之内的事情, 发生概率较大; 异常通常是预料之外的,发生概率极小,但也可能发生。 正常与错误的区别在于,一个是预期的,一个是不期望的。

       PS: 有人会问: 那么发生概率很小但却是期望的事情是什么呢?  ------ 那当然是 Surprise 啦!

        

        明确正常、错误和异常的共同点和区别对于编写健壮性好的程序是必不可少的。通常,我们更注意处理正常情况,那被看作是一种必须完成的“功能或特色”,是最起码的要求; 错误是不期望的,但也是必须处理的。异常是不曾预料的,是必须做一手防备的。 正常情形通常是程序的主控制流, 错误情形作为程序的分支, 而异常处理则作为一种高层戒备。 程序的结构基本是这样的:

String result = DEFAULT_VALUE;
try {
    doSome1();    // 正常流
    if (error) {        //  错误情形的分支处理,相当于关卡
        return ERROR_INFO;
    }
    return result;   
}
catch (SomeException se) {   // 异常情形
    logger.error(e);          
    return EXCEPTION_INFO;
}
finally {
    cleanup();
}

      1.  初始值要认真考虑,不要随手设置。 最好设置为默认值。

      2.  try {}  块里面包含了正常和错误情形的处理, 正常情形是主控制流, 错误情形是分支处理(既然预料到了,就必须加以处理了)。 异常则在 try 之外, 因为是预料不到,要防一手。 

      3.  无论底层会出现什么错误, 高层总是会返回一个合理的值。所有的情况,包括异常也被处理了。

      4.  使用卫述句式。错误情形处理总是会导致一大堆 if-else , 降低程序可读性。对比一下:

            if (正常情形) {   doNormal(); }                   VS:             if(someError) { doSomeError(); return SOME_ERROR_INFO1 };

            elseif(SomeError) {doSomeError();}                        if(someError2) { doSomeError2(); return SOME_ERROR_INFO2 };

            else {doSomeError2(); }                                              // continue normal doing.

            反正我更倾向与后者呈现的结构。

       5.  出错了总是会返回某种信息,交由高层处理。 总有一层能够合理处理。可以返回默认值,抛出异常,或交由更高一层, 或者什么都不做,直接忽略。 总要采取一种措施。

       6.  由于错误涉及到底层到高层的传递,甚至传递不只一层, 因此, 是一个整体构架的问题。 应该从整体上仔细设计。

       

原文地址:https://www.cnblogs.com/lovesqcc/p/4037788.html