异常处理设计
程序执行过程中,对于可以预测的不符合程序本身逻辑的操作,都可以归为异常。包括输入异常,执行异常,数据异常等。区分的方式复杂多样。
一般的处理异常方式有两种,一种是try-catch形式对异常进行捕捉及处理,一种是直接使用if语句捕捉。
异常的处理需要专门的设计。任何使用程序的人都不希望经常见到各种异常的抛出。未经设计的异常处理模式要么直接被忽略(pass),要么直接被抛出(raise)。这两种都是异常的处理操作,但是什么时候该忽略什么时候该抛出需要仔细的思考。
如同面向对象设计模式中,希望一切的操作都被封装,最后只提供几个非常简单的接口进行访问一样,对于异常的处理也应该是如此。对于每一个接口的操作,被深度封装后的内部逻辑将有一定的复杂度,难免会带有复杂的异常情况。而对于异常应该封装成几个用户需知的类型,告诉用户接口访问失败的原因即可。但是不需要告诉他具体是在执行哪一步的时候出现了错误。比如一个页面的资源可能分布在不同的服务器,加载一个页面需要访问多个服务器以拿到所有的资源。当某一个资源不可达的时候,只需要说明网络有问题,导致某个资源访问不到即可,不需要说明是哪一个服务器,不需要说明是访问超时或是资源不存在或是其他的原因。因为访问页面的用户并不关心这一些。同样的,对于删除文件操作,如果是删除一个不存在的文件,只需要正常返回即可,给予一个文件不存在的warning甚至只是info信息即可,不需要给一个error的信息。因为删除一个不存在的文件本身能得到的返回的结果是让文件不存在,即是说结果达到预期,不需要报错。
所以相应的也涉及到了一个日志分级的问题。info、debug、error三个级别对应的用户是不一样的,什么样的用户需要访问什么级别的日志,获取什么类型的异常需要分清楚。一个信息属于哪一级别也要经过思考。最简单的判断逻辑是,用户的输入经过该接口的处理,输出结果与用户的期望结果相差多大。
这在用户友好型的程序设计中非常关键。也是降低程序复杂度的一个关键。