Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
A response to Validation in a DDD world

Jimmy Bogard presented a well written argument for always keeping validation out of entities in a domain driven design except in "the absolute worst case."  But, IMO, there is simply no black and white verdict on where validation must live in a DDD application and must be carefully considered at the beginning of any project, taking into consideration the motivations behind validation, the scope of the project, the maturity of the development team, and the balance between philosophical purity and practical maintainability.

There are two clear project scenarios which come to mind when I try to answer where validation should live.  The first is wherein a DTO layer is used to transfer information between the view and domain layers.  For example, you may have a Customer object in your domain layer and an associated Customer DTO in another layer to which you map the Customer information, to then give to the view for presenting Customer information to the user.  The second scenario is a project wherein the entities within the domain layer are shared directly with the view to present the data to the user.  For example, instead of maintaining a separate DTO layer and mapping domain object to the DTOs to be given to the view, the view could be given the Customer object directly.  So instead of talking via a separately maintained DTO to show a Customer's name, the view would simply ask the Customer object itself for the information.

The primary benefit of a DTO layer is that it provides a clean separation between the view and the domain model.  (This is admirable and even ideal from a theoretical perspective.)  The major drawback is that you end up maintaining a nearly object-for-object replicated layer, reflecting the properties of the entities and value objects found within the domain layer.  This layer can become quite cumbersome and resistant to change as a project enters maintenance.  The latter approach, wherein the entities are exposed directly to the view, removes the surgical separation of the view's knowledge of the domain, thus eliminating the need to maintain DTOs for every bit of information given to the view.  The major drawback to this is that a developer could start doing all of their business logic in the view itself (within server side scripting tags anyway) and that an entity could be put into an invalid state if they're also being used to capture data directly from a form.  The former is a reflection of developer maturity and team agreement.  (But if you have developers trying to do their business logic within server side script tags in the views, you'll likely have bigger worries than debating the finer points of the art of DDD.)  The latter, wherein an entity can end up in an invalid state, is cause for further conversation...

Is it still domain driven design if an entity can enter an invalid state?  The core of domain driven design is that the primary focus is on the domain and domain logic.  Accordingly, the model is a reflection of the domain.  But does allowing an entity to enter an invalid state preclude the model from being a reflection of the domain, or that the domain is no longer the primary focus of the project?

Suppose your business accepts purchase orders via fax machine.  This purchase order is an entity, albeit a paper one at that.  Now suppose that someone faxes you a purchase order but forgets to add their email address, which you require to fulfill the purchase order.  Is it no longer a purchase order simply because they've left off their email address?  I would argue that it's an incomplete purchase order that cannot yet be fulfilled until the remaining details are captured; i.e., it's an entity in an invalid state.  Accordingly, it's not one you're going to want to take action on and "file away."  That doesn't mean that your business is flawed or that you have to yell at the person who placed the order (analogous to throwing an exception).  It also doesn't mean that you must maintain two forms, one for the user to submit the information on, and another for you to copy the information over to if the first form was 100% completed.  You'd simply ask the person for the additional information and proceed, accordingly.  The point is that allowing an entity to enter an invalid state should not be seen as being mutually exclusive from developing a domain driven application.

So where validation lives depends on which approach you take to your application.  If you maintain a DTO layer, then the DTOs which capture information from forms should be validated and you should have additional logic in place to ensure that your entities can never enter an invalid state.  The easiest way to do this is to expose a constructor which accepts the minimum amount of information for the entity to be in a valid state and to use design-by-contract rules to ensure that the arguments passed to the constructor are consistent with a valid state, accordingly.  You could also pass the DTO object itself to the constructor and make sure the DTO is valid before settings its values to the properties of the entity being constructed.

Alternatively, if you do not maintain a separate DTO layer and expose entities to the view for consumption and updates, then it is necessary to maintain the validation within the entities themselves to ensure that they do not get persisted in an invalid state and to communicate to the user what needs to be done to get the entity into a valid state.

Earlier, I mentioned that maintaining a separate DTO layer is the correct approach from a theoretical perspective.  But it comes with a cost to maintainability, simplicity, and readability.  Exposing the entities directly speeds development and makes the design easier to change down the road (since you don't have to keep two layers in synch with each other) but diminishes the purity of separation between view and domain and allows entities to be in invalid state, temporarily as they may be.  Accordingly, you must consider the balance between philosophical ideals and practical maintainability on any project.  When it comes down to it, the client that you're developing for couldn't care less which approach you're taking...as long as it gets them their solution delivered in a timely manner, with a high level of quality, and which they're not going to have to pay an arm and leg to have changes made to it down the road.  It's up to you and your team to determine which approach is most appropriate for the task at hand, meeting the goals of both the client and the development team, while considering what's in the best interests of the long term maintainability of the project.

Even though I'm suggesting that there's no hard rule to which approach you should take with respect to domain/DTO organization and the appropriate location of validation, I do have a suggestion for a rule of thumb.  For very small and simple projects (e.g., a small ecommerce store or an Access-like CRUD app), the active record pattern is a solid approach and you should adhere to the validation guidance of whichever implementation you use (e.g., Castle ActiveRecord).  Alternatively, for a large proportion of web-based business applications, which fall into the large, middle portion of a normal curve if you will, maintaining validation within the domain layer is perfectly adequate while still supporting a maintainable, domain driven design.  (The use of NHibernate Validator attributes within entities is fine in these situations, IMO.)  Finally, for very large and/or complicated projects, or one with a large team (7 or more?) separated into very discrete roles, maintaining a separate validatable DTO layer, separate from the entities, and keeping entities from ever entering an invalid state is likely a good approach.  (Jimmy Bogard's AutoMapper is a great tool for assisting with transferring information between DTOs and entities BTW.)

So while the use of a DTO layer and separated validation from entities is appropriate in some situations, and ideal from a philosophical perspective, the use of validatable entities is very practical and maintainable in a good proportion of web application scenarios as well.  When it comes right down to it, it's up to your team to decide which approach is best for the project at hand.

Billy McCafferty


Posted 02-17-2009 1:08 PM by Billy McCafferty

[Advertisement]

Comments

DotNetShoutout wrote A response to Validation in a DDD world - Billy McCafferty
on 02-17-2009 3:31 PM

Thank you for submitting this cool story - Trackback from DotNetShoutout

new ThoughtStream("Derick Bailey"); wrote Proactive vs Reactive Validation: Don’t We Need Both?
on 02-17-2009 8:17 PM

Update: There’s a wealth of knowledge out there that I just haven’t been aware of until now. Thanks to

DotNetKicks.com wrote A response to Validation in a DDD world
on 02-17-2009 10:50 PM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Jake Kim wrote re: A response to Validation in a DDD world
on 02-18-2009 12:27 AM

I have a question about the state of an entity. In your example, a faxed purchase order with a missing email address is an entity in invalid state.

But if the business allows orders through fax, shouldn't it be captured in design as a different type of order? that can be in its own valid state as it is but only invalid from "complete" order's standpoint?

Gilligan wrote re: A response to Validation in a DDD world
on 02-18-2009 8:56 AM

I think Jake has a point. The entity is not actually invalid. If we looked at a purchase order in isolation, then having a blank email is perfectly alright. But then we move a level up and see that the order is invalid for completion. So it is the Order Fulfillment operation that is invalid, not the actual order. Thus the validation should probably be on the Order Fulfillment service/entity/ Aggregate component /etc.

pablo cibraro wrote re: A response to Validation in a DDD world
on 02-18-2009 10:08 AM

Adding validations in the DTO is not possible for some scenarios, for example, if you expose those DTOs as part of a web service operation. In that case, the client application would ideally recreate the DTOs using the service's WSDL, so all the validation magic will dissapear. What would be the right approach in your opinion for those scenarios, only validate the data on the service interface or duplicate those validations on the client side as well ?.

Billy McCafferty wrote re: A response to Validation in a DDD world
on 02-18-2009 11:45 AM

@pablo,

We're crossing the same bridge quite soon on a project I'm working on.  We're going to be creating a shared DTO library with validation on the DTOs themselves.  In this way, there's no duplicated code (between client and server) and both projects share an understanding of validation.

Billy McCafferty wrote re: A response to Validation in a DDD world
on 02-18-2009 12:07 PM

@Jake and Gilligan,

That's a very interesting idea of moving the validation, for that particular example, onto the Order Fulfillment service.  But if that's the case, isn't the Order Fulfillment validation based on a validation of the Purchase Order itself?  In other words, you'd still need to determine if the Purchase Order is in a valid state in order for the Order Fulfillment service to determine if it can proceed.  This brings up another very interesting question (one with an equally long answer - which I do not have - as my blog post), is it ever appropriate for an entity to have knowledge of whether or not it is valid or should it's validity always be determined by the thing which uses it for some purpose.  For example, the Purchase Order may not care that the email address is left off, but the Order Fulfillment service does.  Does validation only make sense in the eye of the beholder?  ;)  But I think that validation can be broken into two categories:  validation which is objective and always required (e.g., a social security number MUST always be provided and MUST adhere to the format of ###-##-####) and validation which is subjective based on the thing which is using it (e.g., the Order Fulfillment service).  With this perspective, it would seem appropriate to add validation to the entity (if you're not using a DTO layer) for the non-negotiable validation rules.  But that the subjective validation rules should be determined by the thing which requires it.

Gilligan wrote re: A response to Validation in a DDD world
on 02-18-2009 3:35 PM

Exactly, Billy. I add any invariants for that entity to the entity itself. So perhaps originally we expected all POs to always have an email address. Then we just put a check in the constructor. But then we have to deal with faxes, which can contain much empty info. Now the email address (and other info) are no longer invariant. Thus we move them to the OrderFullment Context. Or we could even subclass A PO and have a POForFulfillment and an ImportedPO then have the Fulfillment Context only accept POForFulfillments.

I feel that validation is really just a part of the bigger Separation of Concerns issue, but we seem to try to make it more. Perhaps because it is a large part.

Personally, having validation in the ViewModel (DTO) layer is good enough  99% of the time.

Joshka wrote re: A response to Validation in a DDD world
on 02-19-2009 2:33 AM

One way of rephrasing this conversation is to percieve entity validity as an attribute of the entity in the PO case, you can have an attribute named "IsComplete" and the OrderFulfillmentService should throw if this is not true.

You might have other attributes like IsOverdrawnCustomer or ... Using IsValid or a validator seems too high level and like it moves away from one of the main principles of DDD, the ubiquitous language.

Some questions that I've been thinking about lately:

Does Validity have any meaning in the domain? Does it have more than one meaning? Is validation something that depends on who / where / when / what is being validated, or even on external factors outside the entity. (e.g. a bank loan request might have been approved, but is not valid for payment because the bank has no money).

A great example is of a video store. A customer is registering, but chooses not to provide an email address.

An email address is required for weekly newsletters, so the customer is invalid for the newsletter service, but the customer is not globally invalid, nor is there two types of customers (one with email, one without). If you take validation too narrowly, you would turn that customer away and not allow them to rent videos. Extend this to having a requirement for proof of identity. You enter a bunch of details into the new customer record, but at the end realise that the customer is missing one detail. They say they'll come back and finish it another day. Again, this customer is probably invalid for the core part of your domain (renting videos), but should probably be saved to your repository so that when they come in tomorrow they can fix the missing details and hire a video without having to re-enter all the missing details.

mwardm wrote re: A response to Validation in a DDD world
on 02-20-2009 5:34 PM

I must read up on this newfangled DDD stuff.  

Aren't my entities allowed to have proper states / statuses any more?  

Adios, draft, approved,invoiced, paid, authorised, placed, dispatched, completed....   It's been fun!

Warren wrote re: A response to Validation in a DDD world
on 02-20-2009 6:00 PM

I think Joshka hit it on the head - the fax is not "invalid", it's only invalid for some purposes. it's not a different entity, and there's no reason not to store it, although there might be a use case that says "contact user if fax is not complete"

Warren wrote re: A response to Validation in a DDD world
on 02-20-2009 6:04 PM

and, in response to mwardm, i'd say, yes, entities can have states. but the states shouldn't have public setters. instead, methods like RecordPayment() should update the state via private setters. or every change to a relevant property can call a private UpdateState() method if the logic is more complex.

it's all situation-dependent, but i've used both of these approaches for different scenarios and been happy with the results.

Billy McCafferty wrote re: A response to Validation in a DDD world
on 02-20-2009 6:41 PM

@mwardm, DDD doesn't remove states and statuses.  As always, status state is situational and can be as simple as a bool to an enum to a full blown state machine.

The validation only concerns itself with whether the internal state of an entity is valid or not-valid according to the business rules of the project.  It doesn't detract from the value of state properties like the draft, approved and paid.

Dominique Ribaut wrote re: A response to Validation in a DDD world
on 02-27-2009 3:09 AM

Hi,

In the article You treated Validation under one umbrella but in the comment it appear that there is at least 2 kind of validation, unbreakable rules (qty must be bigger than 0) and context sensitiv rules (need an email adress)

IMHO The first category should be coded on the entity  no matter wath as it should raise an exception if this is broken.

The second one is depending of the context and a validator seems better suited to do the job. This is particulary true if you are a "product" shop, i.e. building a software that you customize for different client or if your application serves multi-tenancy.

If your context dependant validation (that's business rules, ist'nt it) change, you just change the spesification of your validator.

Such a validator can be used by several client like a orderCandidate DTO or an order entity.

--

Dom

joey wrote re: A response to Validation in a DDD world
on 03-04-2009 7:31 AM

Are you sure we are talking about DTO's or PresentationModels?  DTO (no behaviour) are for over the wire while it sounds like your article is more about PresentationModels where there is some behaviour allowed with validation...

Billy McCafferty wrote re: A response to Validation in a DDD world
on 03-04-2009 9:21 AM

Hi joey,

Your distinction is correct.  I'd go as far as to call a Presentation Model a *type* of DTO.  But I may be splitting hairs here. ;)

Alex Locher wrote re: A response to Validation in a DDD world
on 03-10-2009 7:37 PM

Billy,

I've got one simple question.

If we are dealing with the "objective and always required validation", which is implemented as part of our domain entity (using NHibernate.Validator or smth.) - shuld we allow to persist entities in the Invalid state to the database? If not, then probably we can  check this Entity.IsValid() from Repository during Save/Update - and interrupt the operation if the entity is invalid? Or you prefer to leave this check for the service/controller?

Thanks.

Billy McCafferty wrote re: A response to Validation in a DDD world
on 03-10-2009 8:00 PM

Alex,

I feel a triple enforcement is good:

1) Use the service/controller layer to check validity before committing to the DB - this is validation enforcement from the business tier;

2) Optionally, but not a bad idea, add an interrupt to an NHibernate listener or interceptor to ensure the object is valid before it gets persisted - this is validation enforcement in the data tier; and

3) Define appropriate column level constraints (foreign keys, not null, max data length, etc.) to ensure data and referential integrity.  Although you could replicate the entire validation logic in the database itself, I personally only use the null/not-null, max length (e.g., varch(200)) attributes at the column level.  Everything else should be enforced by the application.  No need to introduce a bunch of extra maintenance IMO.

Let me know if that isn't clear or if you have a comment about this.

Jak Charlton wrote re: A response to Validation in a DDD world
on 03-11-2009 4:18 AM

Perhaps worth reading along these lines:

devlicio.us/.../ddd-invariants-or-contextual-validation.aspx

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)