2012-03-22 33 views
5

一个实体(比方说一个UserEntity)对它的属性有严格的规则,它可以存在两种状态 - 持久化(意味着它有一个id)和预先持久化(这意味着它还没有id)。如何在持久化之前处理域实体验证?

根据对this question about how to handle required properties的回答,“真正的”用户实体只能通过传递给其构造函数的id创建。

但是,当我需要从浏览器发送的信息创建一个new UserEntity时,我需要能够在持久化到db之前验证信息。

在过去,我会简单地创建一个空白UserEntity(无id),设置新的属性,以及验证它 - 但是,在考虑实体的这种新的,更安全的方法,我不应该永远创建一个不带id的新UserEntity。

我不想创建两个知道如何验证我的UserEntity属性的地方,因为如果他们改变了(他们会改变的话),它将会更新代码两倍并且增加错误的几率。

如何有效地集中我实体属性的验证知识?

注意

我有一个想法体现in this question,其中我认为存储在标准值对象,它会知道有关它的性质的规则,如电子邮件,密码和名字的非国有性质不同的服务,如Controller,Validator和Repo或Mapper可以使用。

回答

4

这就是工厂的用途。在工厂方法中,您仅传递实施UserEntity的实际不变量所需的数据(需要一些时间来弄清楚您的UserEntity的不变量是什么,并且您最好使用您的领域专家来做)。

在工厂方法

您创建一个新的ID,并把它传递给UserEntity构造。

在这个阶段,我不认为如果构造函数内部的验证失败,那么抛弃实例就不好。在最糟糕的情况下 - 你失去了一个ID ...假设经常发生的情况并非如此 - 大多数情况下数据应该在客户端进行验证。

当然,另一种选择是,在工厂方法首先验证参数,然后才创建一个新的ID,并将其传递给UserEntity构造。

itzik saban

+0

任何人都可以用更简单/不同的方式解释这个吗? – johnnietheblack 2012-03-22 21:39:31

0

在我看来,保存()和load()方法应该做的事情都验证和设置ID属性。顺便说一下,没有身份属性的实体根本就不是一个实体。

在我看来,身份属性应该进行验证,并确保当实体是在运输过程中如从数据库

装载,从文件或(后)保存加载到数据库,从而

如果从数据库加载失败丢弃保存到数据库/文件的实体不会丢弃该实体。

由于验证是商业记录/行为等,并为更好的模式将是

策略模式(http://en.wikipedia.org/wiki/Strategy_pattern)

+0

save()和load()方法应该存在于这个想法中......实体本身还是像映射器那样的其他位置? – johnnietheblack 2012-03-22 22:02:58

+0

显然在父实体是具体的。验证是一种行为,在我看来,它本身并不是强制性的。例如,当您启动一辆汽车时,可以说它的光线持续亮起,如果不是它仍然是一辆汽车。 – sakhunzai 2012-03-22 22:12:04

1

我认为你有一个夫妇的选择可以考虑:

(1)考虑您的第一个评论:

的实体(比方说,一个UserEntity)有严格的规则为它的 properti它可以存在于2个状态 - 持久化(这意味着它 有一个id)和预先持续的(这意味着它还没有一个id)。

在这里,你已经提到验证实际上取决于实体是否被持久化。换句话说,如果实体没有被持久化,那么它应该没有ID是有效的。如果继续使用该域名规范,我觉得确认应当采取相应的行动(如返回的isValid即使没有如果对象没有被持久化的ID)

(2)如果假设“有效”是指对象有一个ID,那么你需要在创建时生成ID。取决于你的ID如何生成,这可能会变得棘手(例如保存到数据库并返回创建的ID,或者以某种方式生成唯一标识符,或...)

使用这两种方法之一,可能值得实现通用基类(es )为您的实体(例如ID),以帮助最大限度地减少在不同州的重复验证。希望这也能保护派生实体免受通用验证。

0

如何正确进行验证的主题有点灰色地带。

通常将验证转换为不变和上下文验证。不变验证属于那些根据您的问题领域必须存在的事物,以使您的模型在其预期的角色中正常工作。上下文验证属于在给定使用情境中有效的状态(例如,用于电子邮件的联系人需要电子邮件地址,但不需要电话号码;用于目录邮件的联系人需要邮寄地址,但不需要电子邮件等)。

如果您希望体系结构纯粹,那么从技术上讲,输入验证(您的客户在用户界面中键入的内容)以及给定实体的状态是两个不同的问题。理想情况下,您的域名应该不知道其编写的特定类型的应用程序,因此不应因提供适合直接或间接使用的错误消息而将错误消息显示回给用户。这带来了一些问题,因为它可能会导致重复或三重错误检查(客户端,服务端,域级),所以很多人选择更实用的方法来处理大多数实体外部验证(例如验证实体创建之前的输入模型)。

0

我没有看到持久无效数据的问题。有效与否是企业关注的问题,有时取决于具体情况。数据库不关心这些业务规则。

如果我必须在网上填写一个大表格,最后一步需要输入我的信用卡信息,并且我没有准备好我的信用卡,那么我将不得不丢弃所有信息,并且下一次再次输入它(这不会发生,因为我宁愿去别的地方)。我希望该应用程序能够存储我已经提供的信息,稍后我可以使其功能有效。只要它无效,我就不能在网上订购东西。

相关问题