如何在MVP /域环境中应用验证?
让我用一个例子来澄清:
域实体:
class Customer
{
string Name;
etc.
}
MVP-模型
class CustomerModel
{
string Name;
etc.
}
我想对我的域实体应用验证,但MVP模型有自己的模型/类 除了域实体,这是否意味着我必须复制验证代码 还可以参与MVP模型吗?
我提出的一个解决方案是删除MVP模型并将域实体用作MVP模型, 但我不想将数据设置为尚未验证的实体。 第二个问题是,如果实体有通知事件, 应用程序的其他部分将受到错误数据的影响。
使用该方法的第三件事是,如果用户编辑某些数据然后取消编辑,我该如何恢复旧值? (实体可能不是来自数据库,因此在所有情况下都不可能重新加载实体。)
另一种解决方案是对相关实体进行某种复制/克隆,并将该副本用作MVP模型,但如果实体具有大型对象图,则可能会遇到麻烦。
任何人都有关于这些问题的一些提示吗?
答案 0 :(得分:4)
限制某人的名称可能不属于域模型,除非在客户的公司中实际存在一条规则,即他们不与名称超过96个字符的客户开展业务。
字符串长度等不是域的关注 - 使用相同模型的两个不同应用程序可能有不同的要求,具体取决于UI,持久性约束和用例。
一方面,您希望确保您的模型完整而准确,但要考虑您正在建模的“真实世界”人物。没有关于长度的规则,也没有关于“oops的逻辑推论,试图给这个人起个名字的问题。”一个人只有一个名字,所以我认为演示者有责任在填充域模型之前验证用户输入的内容,因为数据的格式是一个关注的问题。应用程序比域名更多。
此外,正如Udi Dahan在他的文章Employing the Domain Model Pattern中解释的那样,我们使用域模型模式来封装可能发生变化的规则。一个人不应该有一个空名称并不是一个可能永远不会改变的要求。
我可能会考虑在域实体中使用Debug.Assert()
只是为了通过集成和/或手动测试增加一层保护,如果我真的担心一个空名称偷偷摸摸,但又像长度,不属于那里。
不要直接使用您的域名实体 - 保留该表示层;你需要它。你直接使用实体列出了三个非常实际的问题(我认为Udi Dahan的文章也涉及到这一点)。
您的域模型不应该默认应用程序的需求,很快您的UI将需要一个事件或集合过滤器,您只需要坚持到该实体。让表示层充当适配器,每层都能够保持其完整性。
让我明确一下,域模型不必缺乏验证,但它包含的验证应该是特定于域的。例如,当试图给某人加薪时,可能要求在最后一个人的6个月内不能获得加薪,因此您需要验证加薪的生效日期。这是一个业务规则,可能会发生变化,绝对属于域模型。