在程序中进行多层数据验证是否可以深入防御故障或代码混乱的偏执?

use*_*725 2 javascript validation defensive-programming

例如,当最初输入数据时,如果它与我的验证正则表达式不匹配,我可能会将其吐出。然后当我需要使用它的时候,我常常会产生这样的冲动:

function useData(data) {
  if(data.match(/some invalidating substring/) throw Error('Shouldn\'t have ever gotten past the orig. regex, but somehow it did, so its good that this extra layer of debugging info was integrated.');
  // actually use the data.
}
Run Code Online (Sandbox Code Playgroud)

我并不是真的在谈论安全性,因为那样你就需要深度防御。我所指的代码类型通常对安全性不敏感,我只是想编写设计良好的代码,很有可能发现错误。从某种意义上说,深度防御也需要防止故障,而且不仅仅是漏洞,我想,但与此同时,Unix 哲学要求代码只做一件事,而且只是做那件事,但要做得好。考虑到这一点,不“信任”您的验证代码来完成其工作,然后在另一个函数中的某个地方制作另一段验证代码,“以防万一”,这似乎是不好的做法。用两段代码做一件事也不是好事。另一个缺点是,如果您更改验证模式,那么您可能会忘记在两个地方都这样做。

反馈?

Rou*_*per 6

这在程序员中是一个宗教问题,但一个合理的方法是遵循契约设计范式,在其中设计遵守契约的函数。合同规定了先决条件、后置条件和不变量。函数应遵守其契约,并且不对契约中未指定的行为提供任何保证。

在每个函数中验证输入是多余的,并且可能会导致代码混乱。考虑一个简单的函数,它接受整数 x 并返回 x 的平方根。您要验证输入以确保 x 为非负数吗?您可以,或者您可以在合同中指定 x 必须为非负数。后者更干净,但需要程序员更加小心才能正确使用它。

不要试图捕获代码中的错误。相反,使用良好的测试框架来捕获错误。