Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validation in a Domain Driven Design

How do you deal with validation on complex aggregates in a domain driven design? Are you consolidating your business rules/validation logic?

I understand argument validation and I understand property validation which can be attached to the models themselves and do things like check that an email address or zipcode is valid or that a first name has a minimum and maximum length.

But what about complex validation that involves multiple models? Where do you typically place these rules & methods within your architecture? And what patterns if any do you use to implement them?

like image 831
Todd Smith Avatar asked Feb 05 '09 16:02

Todd Smith


People also ask

What are the rules of DDD?

In DDD, validation rules can be thought as invariants. The main responsibility of an aggregate is to enforce invariants across state changes for all the entities within that aggregate. Domain entities should always be valid entities. There are a certain number of invariants for an object that should always be true.

What is the purpose of Domain-Driven Design?

Domain-driven design is the idea of solving problems of the organization through code. The business goal is important to the business users, with a clear interface and functions. This way, the microservice can run independently from other microservices.

What is domain-driven design example?

An aggregate is a domain-driven design pattern. It's a cluster of domain objects (e.g. entity, value object), treated as one single unit. A car is a good example. It consists of wheels, lights and an engine.

What is the domain model in domain-driven design?

The Domain Model is your organised and structured knowledge of the problem. The Domain Model should represent the vocabulary and key concepts of the problem domain and it should identify the relationships among all of the entities within the scope of the domain.


2 Answers

Instead of relying on IsValid(xx) calls all over your application, consider taking some advice from Greg Young:

Don't ever let your entities get into an invalid state.

What this basically means is that you transition from thinking of entities as pure data containers and more about objects with behaviors.

Consider the example of a person's address:

 person.Address = "123 my street";  person.City = "Houston";  person.State = "TX";  person.Zip = 12345; 

Between any of those calls your entity is invalid (because you would have properties that don't agree with each other. Now consider this:

person.ChangeAddress(.......);  

all of the calls relating to the behavior of changing an address are now an atomic unit. Your entity is never invalid here.

If you take this idea of modeling behaviors rather than state, then you can reach a model that doesn't allow invalid entities.

For a good discussion on this, check out this infoq interview: http://www.infoq.com/interviews/greg-young-ddd

like image 129
Ben Scheirman Avatar answered Sep 29 '22 23:09

Ben Scheirman


I like Jimmy Bogard's solution to this problem. He has a post on his blog titled "Entity validation with visitors and extension methods" in which he presents a very elegant approach to entity validation that suggest the implementation of a separate class to store validation code.

public interface IValidator<T> {     bool IsValid(T entity);     IEnumerable<string> BrokenRules(T entity); }  public class OrderPersistenceValidator : IValidator<Order> {     public bool IsValid(Order entity)     {         return BrokenRules(entity).Count() == 0;     }      public IEnumerable<string> BrokenRules(Order entity)     {         if (entity.Id < 0)             yield return "Id cannot be less than 0.";          if (string.IsNullOrEmpty(entity.Customer))             yield return "Must include a customer.";          yield break;     } } 
like image 45
David Negron Avatar answered Sep 29 '22 23:09

David Negron