防御性编程几大基本原则

2023年 12月 8日 30.5k 0

当开发人员遇到意外的错误无法修复时,他们会“添加一些防御性代码”来使代码更安全,更容易找到问题所在。有时候,仅仅这样做就能解决问题。他们会加强数据验证——确保检查输入和输出字段以及返回值。审查并改进错误处理——也许在“不可能”的情况周围添加一些检查。增加一些有用的日志记录和诊断功能。换句话说,这些本应该从一开始就存在的代码。

防御性编程的整个目的是为了防范你意想不到的错误。

——Steve McConnell,《代码大全》

防御性编程的几个基本原则在Steve McConnell经典著作《代码大全》中有详细解释:

保护你的代码免受“外部”传入的无效数据影响,无论你认为“外部”是指什么地方。这里指来自外部系统、用户、文件或模块/组件之外的任何数据。建立“壁垒”、“安全区域”或“信任边界”——边界之外的一切都是危险的,边界之内的一切都是安全的。在壁垒代码中,验证所有输入数据:检查所有输入参数的正确类型、长度和取值范围。再次检查限制和范围。

在检查完坏数据后,决定如何处理它。防御性编程并不意味着吞没错误或隐藏错误。它是关于在健壮性(如果遇到可处理的问题则继续运行)和正确性(永远不返回错误结果)之间做出权衡。选择一种处理坏数据的策略:立即返回错误并停止运行(快速失败),返回一个中立值,替换数据值等等。确保策略明确且一致。

不要假设你代码之外的函数调用或方法调用会按照广告所述正常工作。确保你理解并测试了周围外部API和库的错误处理机制。

使用断言来记录假设,并突出显示“不可能”的条件,至少在开发和测试阶段如此。这对于长期由不同人维护或高可靠性代码特别重要。

巧妙地添加诊断代码、日志记录和跟踪功能,以帮助解释运行时发生了什么问题,尤其是当遇到问题时。

标准化错误处理。决定如何处理“正常错误”或“预期错误”和警告,并始终保持一致。

只在需要时使用异常处理,并确保你对语言的异常处理机制了如指掌。将异常作为正常处理流程的一部分的程序会遭受经典意义上代码结构混乱的可读性和可维护性问题。

Michael Nygard在《发布!》中还提到了其他几个规则,比如永远不要无限期等待外部调用,尤其是远程调用。当出现问题时,无限期可能会很长时间。使用超时/重试逻辑以及他的断路器稳定模式来处理远程故障。

对于C和C++等编程语言,防御性编程还包括使用安全函数调用来避免缓冲区溢出和常见编码错误。

原文:https://swreflections.blogspot.com/2012/03/defensive-programming-being-just-enough.html

 

相关文章

塑造我成为 CTO 之路的“秘诀”
“人工智能教母”的公司估值达 10 亿美金
教授吐槽:985 高校成高级蓝翔!研究生基本废了,只为房子、票子……
Windows 蓝屏中断提醒开发者:Rust 比 C/C++ 更好
Claude 3.5 Sonnet 在伽利略幻觉指数中名列前茅
上海新增 11 款已完成登记生成式 AI 服务

发布评论