Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
593 views
in Technique[技术] by (71.8m points)

.net - Should domain objects be allowed to be temporarily invalid, and how does that decision affect validation techniques?

I'm writing a VB.NET Winforms project based on MVVM (using Winforms binding). My instinct is to never allow a domain entity be in an invalid state. This requires that I do validation checks in the constructor for new entities and in each setter for existing entities:

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

Then I ran across Data Annotations, which seemed pretty slick. I noticed that most people using Data Annotations allow the domain entity to become invalid temporarily, and then validate the entity at some later point with a call to Validate.ValidateObject. By this point the entity is invalid and the original state has been lost unless you have some other mechanism to roll it back.

Two Questions:

1) Do you allow domain entities to become temporarily invalid?

2) Based on your answer to #1, what techniques do you use to validate the entity?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your instinct is right. In DDD objects should never be allowed to enter a state that is not valid from domain perspective. Even temporarily. Objects should protect their internal invariants, this is pretty basic OOP. Otherwise it would not be an object but just a dumb data container. Often times people get confused by the UI frameworks or they overgeneralize the term 'validation'.

For example every Product in your system should have SKU. Or every Customer should have social security number. Enforcing these rules is the direct responsibility of Product and Customer entities. Good old ArgumentNullException will let client code realize that it broke some invariant. Enforcing this rule is not a responsibility of UI or some abstract 'Validator'. If you let this rule be enforced outside your entity you will:

  • eventually end up with invalid state which can result in crash or will require you to write some compensation code to avoid this crash

  • more importantly, you will not be able to reason about the Product by just reading Product code

Furthermore business rules are usually more complex than that so it would be even harder to enforce them outside of the entity without breaking its encapsulation. There is another group of rules that can be easily enforced by using DDD Value Object. In the above example you would create class 'SKU' and 'SocialSecurityNumber'. These classes will be immutable and will enforce all the formatting rules. They can also have static methods like:

SocialSecurityNumber.TryParse(String untrustedString, out SocialSecurityNumber)

or

SocialSecurityNumber.IsStringValid(String untrustedString)

UI can use these methods to validate user input. There is no reason for UI to 'break' objects even temporarily. If you let this happen you will end up with Anemic Domain Model. Unfortunately a lot of sample code on the internet promotes this approach. The bottom line is that your validation rules are coming from your domain and they should be enforced by domain objects.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...