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
DDD: Validity, Consistency and Immutability

There seems to be some confusion around these and similar concepts, so I thought it might be an idea to provide some clarification. Now these things aren’t specific to DDD, but they certainly have a lot of relevance there, and often provoke furious debate.

In this series I first mentioned these things back when I introduced Entities and Value Objects, I said that you should try and ensure Entities are valid at all times,  and that Value Objects should be immutable. The discussion around Aggregates and Aggregate Roots has also proved to be of some confusion, the definition from Eric Evans of an Aggregate says “A set of consistency rules applies within the Aggregate's boundaries”.

Download the ebook of the series so far   (also published on dddstepbystep.com)

Validity

The term “valid” has many meanings in many contexts. When it was mentioned with regards to an Entity, I suggested that you should attempt to ensure that your Entities are always in a valid state, and cannot become invalid. I followed up that this could be achieved by removing property accessors, and only using either constructors or strongly named methods.

Let us go back to our Customer example, and presume that for a Customer to be valid within our Domain, it must have a CustomerNumber, a FirstName, and a LastName. It may also have half a dozen other properties.

So we can ensure this Entity never becomes invalid by removing the property accessors  for the CustomerNumber, FirstName, and LastName, and providing a single constructor that allows us to create a new Customer … Customer(customerNumber, firstName, lastName)

Now there is no possibility that this Customer can become invalid – it either has these three properties or it cannot be created. If we want to be able to change the Customer’s name, we can create a new method .UpdateName(firstName, LastName)

By taking this approach, we ensure that the entity can never be put into an invalid state, for example a developer setting a .FirstName property, but forgetting to set the LastName at the same time.

Some have taken this concept too far, and assume that as a Customer also has a Policy, that it must always have one of these or it is invalid. Of course, there are things we may want to do with our Customer that will require it to have a Policy, but that does not constitute an invalid Customer, it constitutes a rule that must be applied before we attempt to take the action.

The purpose of ensuring the Entity is always valid prevents us having to do messy things like checking an .IsValid() method every time we want to persist our entity, or we write a function that accepts an instance of our entity. Enforcing an “always valid” approach will mean that we do not have to code multiple guard clauses scattered across our applications.

Consistency

The term consistency has come up in this series and around DDD mailing lists. In this respect, consistency is the idea that one piece of data in the system is consistent with another. Here is the bad news:

You cannot ever achieve total consistency

OK – headline over. The point is that something in your application will always be inconsistent. The best example is that when your users have chosen to edit the Customer on their screen they have a copy of that data. By the time they have received that data it will potentially be inconsistent with the domain, and with your persistence store – after all this is why we have the concepts of optimistic and pessimistic locking. When they submit a change to the Customer, it is probably minutes out of date.

Back to our headline, when you accept that it is impossible to achieve total consistency, you can deal with the real problem – how you achieve eventual consistency. Eventually messages will make their way through our domain, eventually data will be persisted, eventually you will have consistency.

While our reporting domain may lag behind our primary domain, does it honestly matter? How important is it that they are both totally consistent? You can certainly achieve a close facsimile of total consistency, but it will come at a high price – does the business want to pay for this?

When you let go of the premise that your data is ever really consistent, it now just becomes an issue of an SLA agreement, if the business really wants data that accurate, then explain the costs and tradeoffs and go with it. If after an explanation they understand that “almost consistent” is good enough for almost all applications, then they just have to make a decision about how important this is to them.

Consistency also applies at a much more granular level, with the domain for example. Entities and Aggregates may be valid, but not consistent with each other at all times. Eventually they should become consistent, but ensuring they are all consistent at all times is very tricky to say the least.

While an Aggregate Root is responsible for ensuring consistency with the Aggregate, it is acceptable, and almost inevitable that Aggregates will be inconsistent with each other at some point in their lifetime.

Again, letting go of the myth of total consistency here will give you far more flexibility.

Immutability

I would hope this is familiar to all – but perhaps some of you saw me mention it and didn’t quite get my context.

The concept of immutability is pretty much what it says – the thing cannot be mutated – or in context, an Immutable Value Object can be created, but can never be changed.

If you want to change an immutable object, then you can create a new one and replace the original.

By making objects immutable, we avoid many problems with validation and consistency, only the constructors on the object matter, and they only need to validate the parameters passed in. It is far easier to check all the parameters at a single time than to check individual properties against each other at a later stage.

 


Posted 03-04-2009 4:47 PM by Jak Charlton

[Advertisement]

Comments

DotNetShoutout wrote DDD: Validity, Consistency and Immutability - Casey Charlton - Insane World
on 03-04-2009 11:56 AM

Thank you for submitting this cool story - Trackback from DotNetShoutout

Bruce Boughton wrote re: DDD: Validity, Consistency and Immutability
on 03-05-2009 2:57 AM

I'm interested how you handle validation feedback in such a system. On submission of a form in the UI, do you apply a set of rules to the raw data before updating the model? What if rules depend on existing values of the model? Or do you create some intermediate objects mimicking the model and apply validation there?

For example, suppose that when updating a customer's delivery addresses, one of the adresses must match their billing address. This rule requires data from the model to determine the validity of the update.

My approach is to bind the incoming data to the domain object then execute a set of validation rules, collect the feedback and only persist the changes if the object is valid.

Reflective Perspective - Chris Alcock » The Morning Brew #300 wrote Reflective Perspective - Chris Alcock » The Morning Brew #300
on 03-05-2009 3:38 AM

Pingback from  Reflective Perspective - Chris Alcock  » The Morning Brew #300

Adam wrote re: DDD: Validity, Consistency and Immutability
on 03-05-2009 3:39 AM

I was just about to ask the same thing.

Jak Charlton wrote re: DDD: Validity, Consistency and Immutability
on 03-05-2009 3:57 AM

Bruce/Adam

Tricky question ... and as I have a terrible cold - I'll only answer briefly

Firstly, the UI probably has different validation to the domain - it is validating input and operations not entities

Secondly, where the validation really is domain validation, then the validation rules should be separated from the entities - the entities/service may call the same logic, but it is not part of them. This allows you to reuse the code in the UI layer, and to use it to generate client validation.

Lastly, trying to throw data into an Entity is the line of last resort ...

As a start I refer you to :

www.lostechies.com/.../validation-in-a-ddd-world.aspx

Another validation blog post is in the works - Greg Young pointed out I may have over simplified it here - which was partly my intention, but it need more clarification

kellyb wrote re: DDD: Validity, Consistency and Immutability
on 03-05-2009 7:55 AM

Thanks for posting this - interesting thoughts.

When I read things like this, the domain modeler in me starts immediately nodding in agreement.

One thing I'm struggling with at the moment is how best to strike the right balance between a domain centric design and an interoperable SAO strategy.  We have a swath of WCF services being consumed by .NET winforms apps, legacy C++ apps, java web apps, etc. and the scale and performance requirements are high.

I assume you're not passing around DTO representations of your domain and not the domain entities themselves in a scenario like this.  In my case we only control the server side processing, and apply a rich domain to a high scale, stateless, SOA architecture for servicing requests at our service layer seems like a mismatch.

If you have any resources on domain design in a scenario like this, I'd love to hear about them.  From what can gather, 98% of the people building web services on the .NET platform are designing them for .NET clients, and therefore have a lot more options working in a domain model approach between client and server.

Jak Charlton wrote re: DDD: Validity, Consistency and Immutability
on 03-05-2009 8:06 AM

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)