防御式编程并不是说让你在编程时持“防备批评或者攻击”的态度,它的主要思想是:子程序应该不因传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据,更一般的说,其核心想法是要承认程序都会有问题,都需要被修改。

1、保护程序免遭非法输入数据的破坏

  • 检查所有来源于外部的数据的值
  • 检查子程序的所有输入参数值
  • 决定如何处理错误的输入数据

2、断言

断言是指在开发期间使用的、让程序在运行时进行自检的代码(通常是一个子程序或宏)。断言为真,表明程序运行正常,否则标示在代码中发下了意料之外的错误。

  • 可以使用断言检查的假定

    • 输入参数或输出参数的取值处于预期的范围内
    • 子程序开始(结束)执行时文件或流是处于打开(关闭)的状态
    • 子程序开始(结束)执行时,文件或流的读写位置位于开头(结尾)处
    • 文件或流已用只读或可读可写方式打开
    • 仅用于输入的变量的值没有被子程序修改
    • 指针非空
    • 传入子程序的数组或其他容器至少能容纳X个数据元素
    • 表已初始化,存储着正式的数据
    • 子程序开始(结束)执行时,某个容器是空的(满的)
    • 一个经过高度优化的复杂子程序的运算结果和相对缓慢但代码清晰的子程序的运行结果一致
  • 使用断言的指导建议

    • 用错误处理代码来处理预期会发生的状况,用断言来处理绝不应该发生的状况
    • 避免把需要知悉的代码放在断言中
    • 用断言来注解并验证前条件和后条件
    • 对于高健壮性的代码,应该先使用断言再处理错误

3、错误处理技术

  • 对于预料中,可能会发生的错误,可以根据所处情形不同,选择以下的方式来处理:

    • 返回中立的值
    • 换用下一个正确的数据
    • 返回与前次相同的数据
    • 换用最接近的合法值
    • 把警告信息记录到日志文件中
    • 返回一个错误码
    • 调用错误处理子程序或对象
    • 当错误发生时显示出错信息
    • 用最妥当的方式在局部处理错误
    • 关闭程序
  • 健壮性与正确性

    正确性意味着永不返回不准确的结果,哪怕不返回结果也比返回错误的结果要好,然而,健壮性则意味着要不断的尝试采取某些措施,以保证软件可以持续运转下去。人身安全攸关的系统更倾向于正确性,消费类应用软件更注重健壮性。

  • 高层设计对错误处理方式的影响

    对错误处理的方式会直接关系到软件是否能满足在正确性、健壮性和其他费功能性指标方面的需求。架构层次需要确定一种通用的处理错误参数的方法,一旦确定了某种方法,就要确保始终如一的贯彻这一方法。

4、异常

异常是把代码中的错误或异常事件传递给调用方代码的一种特殊手段。审慎明智的使用异常,可以降低复杂度,草率粗心的使用会让代码变得几乎无法理解。

  • 用异常通知程序的其他部分,发生了不可忽略的错误
  • 只在真正例外的情况下才抛出异常
  • 不能用异常来推卸责任
  • 避免在构造函数和西沟函数中抛出异常,除非你在同一个地方捕获
  • 在恰当的抽象层次抛出异常
  • 在异常消息中加入关于异常发生的全部信息
  • 避免使用空的catch语句
  • 了解所用函数库可能抛出的异常
  • 考虑创建一个集中的异常报告机制
  • 把项目中对异常的使用标准化
  • 考虑异常的替代方案

5、隔离程序,使之包容由错误造成的伤害

以防御式编程为目的而进行隔离的一种方法,是把某些接口选定为“安全”区域的边界。对穿越安全区域边界的数据进行合法性效验,并当数据非法时做出敏锐反映。

在输入数据后,应当立即将其转换成恰当的类型。

隔栏是一种容损策略。隔栏的使用使断言和错误处理有了清晰的区分。隔栏外部的程序应使用错误处理技术,在那里对数据做的任何假定都是不安全的。隔栏内部的程序里应该使用断言技术,因为传进来的数据应该已经被清理过了。

6、辅助调试的代码

  • 不要自动地把产品版的限制强加于开发版上
  • 尽早引入辅助调试的代码
  • 采用进攻式编程
  • 计划移除调试辅助的代码
  • 编写你自己的预处理起
  • 使用调试存根

7、确定在产品代码中该宝牛多少防御式代码

  • 保留那些检查重要错误的代码
  • 去掉检查细微错误的代码
  • 去掉可以导致程序硬性崩溃的代码
  • 保留可以让程序稳妥崩溃的代码
  • 为你的技术支持人员记录错误信息
  • 确认留在代码中的错误信息是友好的

8、对防御式编程采取防御的态度

过度的防御式编程也会引起问题。防御式编程引入的额外代码增加了软件的如咋读,防御式编程引入的代码也并非不会有缺陷。

更多有关《代码大全 2》的读书笔记,请关注 :
http://tabalt.net/blog/code-complete-2-reading-notes/

本文链接:http://tabalt.net/blog/cc2-defensive-programming/,转载请注明。