【问题标题】:Increasing performance on data validation提高数据验证的性能
【发布时间】:2009-12-15 14:54:22
【问题描述】:

以下示例显然是虚构的,但它恢复了在我正在使用的代码库上完成验证的方式。

TypeA 有两种方法,具有以下签名:

public void FirstMethod(TypeB param)
public ValidationResult TryFirstMethod(TypeB param)

调用 FirstMethod 时,需要对参数进行验证。
因此,它调用 TryFirstMethod 来检索表示验证结果的对象。
如果 ValidationResult 的实例表明一切正常,则继续执行,否则将引发异常。

TryFirstMethod 的作用是调用者,一个假设的 TypeC,可以执行这个方法并检查实际的方法是否会抛出。通过检查 ValidationResult 上的属性。
此外,ValidationResult 的实例包含有关输入错误的原因、如何修复等信息。
这证明了需要这种类型而不是仅仅使用布尔值。

实际上这工作得很好,很容易验证数据并将本地化的错误消息返回给用户。

唯一的问题是,由于某些检查非常复杂,因此执行两次会变得有点贵。
它们最初由调用者完成,以确保实际方法不会抛出。
然后再次通过相关方法检查输入是否有效。

我找不到避免执行两次检查的干净方法。
让事情变得更复杂的是,解决方案应该使用标准方法、构造函数以及当 TypeB 是像字符串或 int 这样的“原始”类型时。

【问题讨论】:

    标签: c# .net security validation


    【解决方案1】:

    听起来你的核心逻辑是这样的:

    1. 验证TypeB(致电TryFirstMethod)。
    2. 如果无效,则显示错误消息。
    3. 如果有效(并且可能其他成员也有效),则对数据执行操作(作为FirstMethod? 的一部分)。
    4. 数据操作 (FirstMethod) 重新验证输入。

    如果这(有些)正确,您应该能够将您的设计更改为:

    1. 致电FirstMethod
    2. 验证数据。
    3. 如果无效,则抛出验证异常。
    4. 如果有效,执行数据操作。

    然后您的 UI 将调用 FirstMethod 并期望操作成功,除非抛出异常,在这种情况下,您将像当前一样显示验证消息。使用这种设计,您只需执行一次验证。

    【讨论】:

    • 是的,你完全理解。事实是异常本身是昂贵的,而且来自外部世界的数据经常是无效的。再次,性能问题。此外,我更喜欢尽量减少例外情况。
    • 与什么相比,异常是昂贵的?如果验证过程如您所说的那样复杂,那么相比之下引发异常的成本可能可以忽略不计。如果抛出异常的成本确实会产生有意义的影响,那么只需像在 TryFirstMethod 中一样返回一个 ValidationResult。
    【解决方案2】:

    既然第一个方法是 void,为什么不直接调用它并让它返回一个 ValidationResult?

    您能否告诉我们为什么第一个和第二个代码具有相同的代码——必须——运行两次?

    您可以简单地让第一个失败并将错误消息传递回该路径中的用户...

    【讨论】:

    • 空白只是为了保持示例简单。通常有一个返回类型。由于我在对 akmad 的回答的评论中解释的原因,我不会专门使用例外。
    【解决方案3】:

    在我看来最干净的解决方案是第三种方法:

    public void FirstMethod(TypeB param, ValidationResult alreadyPerformedResult)
    

    因此用户可以进行自己的检查,使用检查结果调用所需的函数。因此,您可以跳过检查,只测试测试结果是否也符合您的标准。

    也许您可以在 ValidationResult 中添加一些内容(例如,在最简单的场景中将函数名称作为字符串),以便您确定给定的结果确实来自此方法,而不是来自另一个名为 TryMethod() 的方法。

    【讨论】:

      猜你喜欢
      • 2021-03-20
      • 1970-01-01
      • 2022-09-27
      • 2014-11-21
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      相关资源
      最近更新 更多