gpt4 book ai didi

.net - 是否应该允许域对象暂时无效,以及该决定如何影响验证技术?

转载 作者:行者123 更新时间:2023-12-04 10:29:23 25 4
gpt4 key购买 nike

我正在编写一个基于 MVVM 的 VB.NET Winforms 项目(使用 Winforms 绑定(bind))。我的直觉是永远不允许域实体处于无效状态。这要求我在构造函数中对新实体进行验证检查,并在每个 setter 中对现有实体进行验证检查:

Public Class Product


Public Sub New(ProductID as Integer, Name as String)

If ProductID > 0 AndAlso Name.Length > 5 Then

_ProductID = ProductID
_Name = Name

Else
Throw New InvalidProductException
End If
End Sub

Private _ProductID as Integer
Public Property ProductID as Integer

Set(value as String)

If value > 0 then
_ProductID = value
Else
Throw New InvalidProductException
End If

End Set

End Property

'Same principle as above for Name setter.


End Class

然后我遇到了 Data Annotations,它看起来很漂亮。我注意到大多数使用数据注释的人都允许域实体暂时无效,然后在稍后调用 Validate.ValidateObject 来验证实体。此时实体无效并且原始状态已丢失,除非您有其他机制来回滚它。

两个问题:

1) 你允许域实体暂时失效吗?

2) 根据您对#1 的回答,您使用什么技术来验证实体?

最佳答案

你的直觉是对的。在 DDD 中,永远不应该允许对象进入从域角度来看无效的状态。哪怕是暂时的。对象应该保护它们的内部不变量,这是非常基本的 OOP。否则它将不是一个对象,而只是一个愚蠢的数据容器。人们经常对 UI 框架感到困惑,或者他们过度概括了“验证”一词。

例如,您系统中的每个产品都应该有 SKU。或者每个客户都应该有社会安全号码。执行这些规则是产品和客户实体的直接责任。好旧的 ArgumentNullException 会让客户端代码意识到它破坏了一些不变量。执行此规则不是 UI 或某些抽象“验证器”的责任。如果您让此规则在您的实体之外执行,您将:

  • 最终以无效状态结束,这可能导致崩溃或需要您编写一些补偿代码以避免此崩溃
  • 更重要的是,您将无法仅通过阅读产品代码
  • 来推断产品。

    此外,业务规则通常比这更复杂,因此在不破坏其封装的情况下在实体之外执行它们会更加困难。
    使用 DDD Value Object 可以轻松执行另一组规则.在上面的示例中,您将创建类“SKU”和“SocialSecurityNumber”。这些类将是不可变的,并将强制执行所有格式规则。它们还可以具有静态方法,例如:
    SocialSecurityNumber.TryParse(String untrustedString, out SocialSecurityNumber)

    或者
    SocialSecurityNumber.IsStringValid(String untrustedString)

    UI 可以使用这些方法来验证用户输入。 UI 没有理由“破坏”对象,即使是暂时的。如果你让这种情况发生,你最终会得到 Anemic Domain Model .不幸的是,互联网上的许多示例代码都在推广这种方法。底线是您的验证规则来自您的域,它们应该由域对象强制执行。

    关于.net - 是否应该允许域对象暂时无效,以及该决定如何影响验证技术?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7093819/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com