第八章:防御式编程
防止非法输入
检查所有来源于外部的数据
检查子程序所有输入参数的值
决定如何处理错误的输入数据
断言
断言是指在开发期间使用的,让程序运行时自检的代码(通常是子程序或宏)。断言为真,表示程序运行正常。
java的断言写法:
assert denominator != 0 : "denominator is unexpected equal to 0."
断言可以检查如下假定:
输入、输出值在预期范围
子程序开始(结束)执行时,文件或流是处于打开(或关闭)的状态
子程序开始(结束)执行时,文件或流的读写位置处于开头(或结尾)处
文件或流已用只读、只写或可读可写方式打开
指针非空
仅用于输入变量的值没有被子程序修改
传入子程序的数组至少能容纳X个数据元素
表已初始化,存储着真实的数值
使用断言的建议:
用错误处理代码来处理预期会发生的状况,用断言来处理绝不应该发生的状况
避免把需要执行的代码放到断言中
对于高健壮性的代码,应该先使用断言,再处理错误。以微软的word为例,在其代码中对应该始终为真的条件都加上了断言,同时也使用了错误处理代码。
错误处理技术
一些错误处理的方法:
返回中立值:有时,处理错误数据的最佳做法就是继续执行操作并简单地返回一个没有危害的中立值。
换用下一个正确的数据:在处理数据流时,有时只需返回下一个正确的数据即可。retry。
返回与前次相同的数据
换用最接近的合法值
把警告信息记录到日志文件
返回一个错误码:可以决定让系统的某些部分处理错误,其他部分则不在局部处理错误
- 设置一个状态变量的值
- 用状态值作为函数的返回值
- 用语言內建的异常机制抛出一个异常
调用错误处理子程序或对象:把错误处理都集中在一个全局的错误处理子程序或对象中。
当错误发生时显示出错消息
用最妥当的方式在局部处理错误
关闭程序
健壮性与正确性
正确性意味着永远不返回不准确的结果
健壮性意味着要不断尝试采取某些措施,以保证软件继续运行下去
异常
异常是把代码中的错误或异常事件传递给调用方的一种特殊手段
在异常消息中加入导致异常发生的全部信息
为技术人员记录错误信息
避免使用空的catch语句
了解所用函数库可能抛出的异常
考虑创建一个集中的异常报告机制
把项目中对异常的使用标准化
隔离程序,使其包容由错误造成的损害
隔栏,是一种容损策略。
把某些接口,选定为安全区域的边界。对穿越边界的数据进行合法性校验,并在数据非法时进行敏锐的反映。
辅助调试的代码
不要自动地把产品版的限制强加于开发版之上。
程序员们常常与这样一个误区,认为产品级的种种限制也适用于开发中的软件。其实并不是,应该在开发期间牺牲一些速度和对资源的使用,来换取一些可以让开发更顺畅的内置工具。
开发时,尽早引入辅助调试的代码;上线时,计划移除辅助的调试代码。
应该使异常情况可以在开发阶段显现,并且在产品运行阶段时可以自我恢复。