1

例如,当最初输入数据时,如果它与我的验证正则表达式不匹配,我可能会将其吐回。然后到了使用它的时候,我经常会有做类似事情的冲动:

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.
}

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

反馈?

4

2 回答 2

4

这是程序员之间的一个宗教问题,但一种合理的方法是遵循按合同设计的范式,您可以在其中设计遵守合同的功能。合同规定了前置条件、后置条件和不变量。功能应遵守其合同,并且不对合同中未指定的行为提供任何保证。

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

不要试图捕捉代码中的错误。相反,用一个好的测试框架来捕捉错误。

于 2013-11-19T03:04:59.060 回答
2

分层的验证方法是合适的,也不过分。虽然您认为应该尽可能避免重复验证是正确的,但有合理的 UX 和测试考虑因素超过了这种担忧。例如,您的业务层中可能有模型验证,该模型验证在您的 UI 层中复制,以考虑用户体验。您的业​​务层不能对您的 UI 层进行任何假设(现在或将来可能会被完全不同的 UI 实现访问),但这并不意味着好的 UI 不应该将验证推向尽可能靠近用户的地方,即使它是重复的逻辑。

一个好的(实用的)验证框架应该通过使验证数据驱动(甚至元数据驱动)来帮助您最大限度地减少这种重复。如果您的 UI 可以从业务层获取验证规则,则它可以在适当的情况下使用这些规则来提供更具响应性的用户体验。

从用户体验的角度来看,决定在每一层执行哪种类型的验证很重要。例如,您不想在用户击键期间进行重量级或长时间运行的验证。

验证的接触点通常是:

击键(字段验证 - 字段是否有效?)

击键(表单验证 - 所有字段是否独立有效,并且一起使用?)

元素更改(字段验证)

元素更改(表单验证)

表单提交(客户字段和表单验证)

表单提交(服务器字段和表单验证)

这个主题有很多变化(如果做得好,即使在击键级别进行一些服务器端验证也不是闻所未闻的)。虽然不完全是验证,但谷歌的即时搜索功能是该技术如何工作的一个很好的例子)。

花一些时间端到端地设计您的验证框架将在未来获得回报。大多数主要框架还内置了验证框架,可以作为很好的起点。

于 2013-11-19T03:17:52.667 回答