繁体   English   中英

抢先验证还是异常处理?

[英]Preemptive Validation or Exception handling?

我试图在两种有关数据验证的模式之间做出选择:

  1. 尝试遵循正常的工作流程,并捕获由我的模型和服务抛出的异常 :唯一/外部约束冲突,空字段,无效参数等...(!!我仅捕获我知道应该的异常)

    • 优点:在我的控制器和服务中编写的代码很少 :我只需要处理异常并将其转录为用户可理解的消息。 代码非常简单易读

    • 缺点:我需要编写特定的异常 ,有时可能会有很多不同的异常。 我还需要捕获和解析数据库异常(违反约束等)的通用PDO / Doctrine异常,以将其转换为有意义的异常(例如: DuplicateEntryException )。 我也无法绕过某些验证 :假设我的模型对象被标记为锁定:尝试删除它会引发异常。 但是,我可能想强制将其删除(例如,出现确认弹出窗口)。 我将无法绕过此异常。

  2. 我使用代码和数据库查询显式测试和预先验证所有内容 例如,在将其设置为模型中的属性之前,我将测试东西是否不为null以及是否为整数。 或者,我将进行数据库查询以检查是否不会创建重复条目。

    • 优点: 无需编写特定的异常 ,因为我会预先验证所有内容,因此无论如何我都不应该进行大量的try / catch。 我也可以绕过一些验证

    • 缺点: 需要在控制器,服务和模型中进行大量测试和验证 我将执行更多查询 (验证部分)。 数据库已经对外键,唯一约束,而不是空列进行了验证 ……我不应该忽略它并自己重新编码。 这也导致非常无聊的代码

我宁愿使用一种模式或另一种模式,而不是混合使用,以使事情尽可能简单。

在我看来,第一个解决方案似乎是最好的,但恐怕可能是某种反模式 还是在其理论简单性的背后隐藏了很难处理的情况?

我建议数据验证应在应用程序的外围进行。 也就是说,应检查任何传入的数据以确保其符合您的期望。 一旦允许进入应用程序,它将不再进行验证,但始终会根据上下文(数据库,电子邮件等)进行转义。这使您可以将所有验证保持在一起,并避免了验证工作的潜在重复(很容易实现)举个例子,数据可以使用两个模型对两次数据进行两次验证。)Joe Armstrong在其关于Erlang的书中推广了这种方法,并且他为telcom电台编写的软件可以运行多年而无需重新启动,因此它看起来确实运作良好: )

此外,模型期望值并不总是与特定界面建立的期望值完全一致(也许表单仅显示了潜在选项的子集,或者该界面包含美国各州的下拉列表,并且模型存储了许多州的状态有时,复杂的界面可以以增强用户体验的方式集成多个不同的模型对象。 虽然对用户很好,但是使用异常方法进行的这些模型的交互可能很难处理,因为某些输入可能是混合输入,而任何一个模型都无法单独验证。 您始终希望确保验证首先和最符合UI的期望,而第二种方法甚至可以使您在最复杂的界面中进行验证。

而且,就周期而言,异常处理相对昂贵。 验证问题可能会非常频繁,因此,我会尽量避免使用昂贵的操作来处理问题,而不是可能会非常频繁。

最后,该模型实际上并不需要进行某些验证,但是可以防止攻击。 虽然您可以将其添加到模型中,但是所添加的功能可以迅速使模型代码变得混乱。

因此,在这两种方法中,我建议第二种方法,因为:

  1. 您可以为应用程序设计清晰的边界。
  2. 所有验证都在一个地方,并且可以共享。
  3. 如果两个或多个模型使用相同的输入,则验证没有重复。
  4. 这些模型可以专注于他们擅长的领域:将抽象实体的知识映射到应用程序状态。
  5. 即使是最复杂的UI,也可以适当地进行验证。
  6. 抢占可能会更有效。
  7. 真正不属于任何模型的,针对安全性的验证任务可以完全添加到应用程序中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM