防御式编程的思想体现在两个方面:

  • 程序对内部错误表现出来的极端脆弱

  • 程序对外部错误表现出来的极端顽强

内部错误是指程序的基本逻辑错误,例如在 zmq 中 套接字范式如果用错,程序会立即崩溃。

外部错误是指由于网络波动、硬盘空间不足等出现的问题。对这类问题应当最大程度进行容忍。

zmq 中就使用了这种思想。

内部错误

断言是让程序变得脆弱的一种方式。当断言条件不满足时,程序会立即退出。当一种错误无论如何都不应当发生时,可以使用断言进行检查,断言可以用来检查:

  • 输入参数或输出参数在预期范围内:例如传入了一个错误地端口号

  • 指针非空

断言只发生在开发和维护阶段,在成品代码中不应当出现断言消息。

此外,当发生了内存不足之类的问题,程序唯一能做的应该是立即关闭程序,不要再运行了。

外部错误

程序应当避免来自外部错误的影响,所谓外部错误也可以用来当作预期会发生的情况,主要方式有:

  • 读输入数据进行检查:

    • 检查所有来源于外部的数据

    • 检查函数中所有输入参数的值

      当输入数据不合法时,程序可以采取以下行为:

    • 返回一个中立值。例如空字符串

    • 返回一个错误代码

    • 抛出异常

    • 返回上一次正确的数据

    • 返回最接近的合法值

    • 在日志中记录警告消息,然后继续执行

    • 调用错误处理子程序

辅助调试的代码

  • 开发期间的代码允许滥用资源以换取对开发效率的支持,而不需要遵循产品代码中对效率、安全等的要求。

  • 尽早进入辅助调试的代码

  • 计划移除辅助调试的代码

进攻式编程

进攻式编程时这样一种思想:在开发阶段让异常情况暴露出来,异常越大越好,而在代码运行期间让其能够容忍这些错误,主要方式有:

  • 一旦出现问题,直接使用断言终止程序。不要给程序员留下继续执行的机会

  • 对分配的所有内存进行填充。以此检查内存分配错误

  • 对分配的文件或流进行填充。依次排除文件格式错误

  • 确保每个 switch 中的 default 或者 else 分支都被断言终止

  • 在删除一个对象之前把他填满一个垃圾数据

  • 在软件发布后将错误保存到日志文件中。

产品代码中需要保留多少防御式代码

  • 保留检查重要错误的代码。例如如果 excel 的计算引擎部分出现问题,应当立即终止

  • 去掉检查细微错误的代码。这里的去掉并不是直接删掉,而是使用预编译等将其删除,抑或是检查到错误后记录到日志中

  • 去掉可以导致程序硬性崩溃的代码。这种代码应当只存在于开发期间

  • 保留能够让程序稳定崩溃的代码。这种程序的崩溃在自己的控制中,可以保留一些调试信息

  • 确保错误消息是友好的

Last moify: 2024-12-23 10:34:06
Build time:2025-07-18 09:41:42
Powered By asphinx