【问题标题】:Application Design - Validation and efficiency应用程序设计 - 验证和效率
【发布时间】:2013-08-19 04:50:18
【问题描述】:

我有一个 ASP.Net 应用程序,它有很多关于对象是否可以提交到数据库的业务规则。

在基本层面上,一个人是冲刺的一部分,冲刺是项目的一部分。

基本规则是:

一个人被分配到一个 sprint,但可能不是一个 sprint 的整个持续时间(有一个开始和结束日期)。因此,当他们分配此人时,他的开始日期和结束日期必须介于(包括)冲刺的开始日期和结束日期之间。

一个项目可以有多个冲刺,但不能在项目开始/结束日期之外。

我的解决方案有一个 UI 项目、服务层、业务层和数据访问层。

我现在正在构建验证,但不确定应该在我的应用程序的哪个级别进行校准。我不相信它在 UI 上,因为那时我需要在我的 ASP.Net 项目上复制验证规则......也许是我的 WinForms 前端......

我认为它应该在业务逻辑中,因为它具有业务规则。因此,我打算创建一个名为“Validations”的类,对于存储到数据库中的每个业务对象,我的 Validations 中有一个名为“IsObjectOK”的方法,接受我想要验证的对象类型,并返回错误列表。

所以:

public List<String> IsObjectOK(SprintDto source)
{
    // Do validations, and return list of errors, or NULL if none
}

验证规则的示例可能是:

var Project = BusinessLayer.GetProject(source.ProjectId);
// check if Start/End dates fall between Project.Start and Project.End dates

如果有问题,请将其添加到错误列表中。

这似乎是个好方法。我正在寻找有关我处理验证的方法的确认,以及任何提示和技巧?我不应该担心数据库命中吗?我的意思是,对于一个 sprint,我可能需要验证大约 6 或 7 条“规则”,所有这些规则都可能从不同的表中获取数据。因此,一次保存需要 7 个数据库查询(加上连接开销)。 (SQL Server 2012)。我认为这不必担心,因为这一切都交给了业务和数据层。

【问题讨论】:

  • 技术取决于,你是在做CI、单例还是命令模式(CQRS),你在用ORM吗?但是,它应该在业务层上,并且对数据库的 7 调用肯定会在大容量应用程序上造成不好的性能。

标签: c# architecture


【解决方案1】:

除非您必须这样做,否则我不会担心数据库命中。 你的架构正确之后,有很多方法可以优化它。一个好的缓存层可以消除其中的大部分,如果没有,您总是可以编写一个单独的域对象,即“SprintValidation”对象,以包含验证它所需的所有数据。

在您知道这是一个问题之前,不要从牺牲您的架构的性能开始。

【讨论】:

    【解决方案2】:

    当一个对象有可能变得不一致时,我总是尽可能早地、尽可能地设置障碍来防止这种情况发生。

    早期

    理想情况下,处于不连贯状态的对象甚至不应该到达 UI 上方的层。日期间隔通常是您在创建或修改 Sprint 时可以在客户端轻松检查的内容。用户将欣赏关于哪里出了问题或不可能的即时反馈(例如灰色按钮),双重保险总是很好。不过,使用更复杂的验证可能不可行。

    坚决

    在业务中,尝试将这些规则建模为执行一次的不变量,而不是您可能需要执行多次的验证。换句话说,确保您的业务对象是always valid

    • 在创建时(在构造函数或工厂中)强制执行不变量,并尽可能使您的对象不可变Value Objects。您的示例中的 PersonAssignment 是一个很好的候选者。值对象是您从不费心修改的简单结构,您只需将它们替换为另一个,因此保持它们始终一致是小菜一碟。

    • 对于您无法明智地使其完全不可变的对象(例如 Sprint),您仍然可以过滤掉对某些字段的不需要的修改。例如,修改属性 StartDate 和 EndDate 的设置器以不接受项目范围之外的日期。

    • 有时,与状态更改相关的业务规则更复杂,并且涉及许多条件。我发现在单一方法中定义业务操作并在其中包含所有不变检查总是更好,而不是让您的实体进入损坏状态并在之后尝试验证它。

    简而言之:将修改的机会缩小到几个地方,毫不犹豫地在那里严格执行,这样你就可以依靠信心而不是怀疑。

    【讨论】:

      猜你喜欢
      • 2013-06-20
      • 2012-11-12
      • 2021-06-10
      • 2011-09-22
      • 2012-02-11
      • 1970-01-01
      相关资源
      最近更新 更多