繁体   English   中英

您在哪里将验证放在具有域驱动设计的项目中?

[英]Where do you put Validation in projects with Domain Driven Design?

我应该在哪里将Domain对象的Validation逻辑放在我的解决方案中? 我应该把它们放在Domain类,Business层还是其他?

我还想利用Microsoft企业库中的验证应用程序块和策略注入应用程序块来实现此目的。

我应该使用什么验证策略来很好地适应所有这些?

提前谢谢!

这取决于。 首先 - 您需要了解您正在验证的内容。

您可以验证:

  1. 您从Http帖子中检索的值可以解析为日期时间,
  2. Customer.Name不大于100个符号,
  3. 客户有足够的钱购买东西。

正如您所看到的 - 这些验证在性质上是不同的,因此它们应该分开 它们的重要性也各不相同 (参见“所有规则不均等”段落)。


你可能想要考虑的是不允许域对象处于无效状态。

这将大大降低复杂性,因为在当前时间范围内,您知道该对象是有效的,您需要仅验证当前任务相关的事物以便推进。

此外,您应该考虑避免在您的域模型中使用工具,因为它应该尽可能地基础设施免费。

另一件事 - 拥抱价值对象的使用。 这些非常适合验证封装。

你可以根据自己的需要做任何一件事。

将它放在域类中可确保始终完成验证,但可以使类膨胀。 它也可能违反单一责任原则,具体取决于您如何解释(它增加了验证的责任)。 将它放在域类中也会限制您进行一种验证。 此外,除非您使用继承,否则可能必须在相关类(DRY)中多次实现相同的规则。 如果您这样做,验证将通过您的域传播。

外部验证(您可以通过DI,工厂,业务层或上下文获取验证对象)确保您可以根据上下文交换验证规则(例如,对于要在部分完成状态下保存的长时间运行的过程,您可以有一个验证对象只是为了能够保存,另一个验证对象是否真的有效并准备好使用)。 您的域类将更简单(更少的职责,尽管您必须进行最小的检查,如空检查,以防止运行时错误),并且您也可以重用相关类的规则集。 验证以这种方式集中在域模型的一个小区域中。 顺便说一句,你可以将外部验证注入域类本身,确保类自己验证,只是不知道它们正在验证什么。

但是无法对验证应用程序块发表评论。总是你必须权衡利弊与缺点,从来没有一个有效的解决方案。

我一般把它放在域对象中。 这是因为域对象是我关注验证的事情所以如果特定对象的规则发生变化,我知道在哪里更新它而不是必须在一些特定的验证类/文件中搜索一堆不相关的实体规则。

我意识到这可能不被认为是POCO,但每个项目都有特定的例外情况,这个通常对我有意义。 同样,在某些项目中,从视图中引用域实体是有意义的,因此,实现IPropertyChanged而不是不断地将值从实体复制到另一组视图特定对象。

我做验证的旧方法是我有一个类似于下面的IValidator接口,每个实体都实现了。

public interface IValidator
{
   IList<RuleViolation> GetViolations();
}

现在我使用NHibernate验证(不需要使用nhibernate ORM来利用验证库。它只是通过属性完成。

//I can't remember the exact syntax but it is very similar to this
public class MyEntity
{

[NHibernateValidation(Length(min=1, max=10)]
public String Name {get;set;}

}

//... and then later ...
NHibernateValidator.Validate(myEntity);

编辑:我删除了我的评论,因为克里斯告诉我它现在与NHibernate验证非常相似,因此过去一般不会成为企业库的忠实粉丝。

首先,我同意@ i8abug。

但我确实想进一步谈谈架构。 这些设计架构中的每一个,如域驱动,都应该被视为一个建议,并经过详细审查。

在每一步中,您都应该问自己,关于您的申请,问题的好处和缺点是什么。

其中很多都涉及添加大量代码并使项目严重复杂化,而且收益甚微。

验证点是一个很好的例子。 正如Stefan所说,单一责任原则基本上说你需要创建一整套其他类,其目的只是验证原始对象的状态。 显然,这为应用程序添加了大量代码。 也许它是为你生成的,也许你必须手写它。 无论如何,更多的代码通常等同于不那么健壮,当然等同于更难理解。

分离所有这些的好处是你可以换掉验证规则。 好的。 缺点是您现在有2个文件可供查看并为每个类定义创建。 即:更多的工作。 您的应用是否需要更换验证规则? 可能不是。 我甚至打赌很少说。

坦率地说,如果你沿着这条路走下去,那么你也可以把所有东西都定义为一个结构,然后让所有这些“帮助”类回过头来处理验证,持久性,设置属性等等,因为这是一个完整的课程给你买几乎没有。

所有这些都说,我倾向于自成一体的课程。 换句话说,他们知道他们的属性如何相互关联,并知道什么是可接受的值。 他们还可以对自己和孩子进行操作。 换句话说,他们知道自己是什么。 这往往会导致简化编码和实现。 它还可以确切地知道修改或更改的位置。 我在这里真正做的唯一分离就是为持久性实现控制反转; 这允许我在运行时交换数据提供者; 这是我已经完成的几个应用程序的要求。

重点是,仔细思考你正在做什么,并决定它是否真的是你在特定情况下的最佳方式。 所有这些编程“规则”毕竟只是建议。

暂无
暂无

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

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