views:

312

answers:

2

Alternatively, is basic entity validation considered a specification(s)?

In general, is it better to keep basic entity validation (name cannot be null or empty, date must be greater than xxx) in the actual entity, or outside of it in a specification?

If in a specification, what would that look like? Would you have a spec for each field, or wrap it all up in one EntityIsValid type spec?

+1  A: 

It seems to me that once people have learned a little about DDD, they pick up the Specification pattern and look to apply it everywhere. That is really the Golden Hammer anti-pattern.

The way I see a place for the Specification pattern, and the way I understood Domain-Driven Design, is that it is a design pattern you can choose to apply when you need to vary a business rule independently of an Entity.

Remember that DDD is an iterative approach, so you don't have to get it 'right' in the first take. I would start out with putting basic validation inside Entities. This fits well with the basic idea about OOD because it lets the object that represents a concept know about the valid ranges of data.

In most cases, you shouldn't even need explicit validation because Entities should be designed so that constraints are represented as invariants, making it impossible to create an instance that violates a constraint.

If you have a rule that says that Name cannot be null or empty, you can actively enforce it directly in your Entity:

public class MyEntity
{
    private string name;

    public MyEntity(string name)
    {
        if(string.IsNullOrEmpty(name))
        {
            throw new ArgumentException();
        }
        this.name = name;
    }

    public string Name
    {
        get { return this.name; }
        set
        {
            if(string.IsNullOrEmpty(value))
            {
                throw new ArgumentException();
            }
            this.name = value;
        }
    }
}

The rule that name cannot be null is now an invariant for the class: it is now impossible for the MyEntity class to get into a state where that rule is broken.

If later on you discover that the rule is more complex, or shared between many different concepts, you can always extract it into a Specification.

Mark Seemann
What if the rule is slightly more complex, as in: ... string Name; //must not be duplicated in the database ...
Burt
Uniqueness constraints can really only be handled in the database itself because of concurrency issues. Even if you were to check for uniqueness up-front, another concurrent write may have inserted the exact same value before you do. This means that you can't encode uniqueness as an invariant, but you can still help the user by doing an up-front check. That, however, is not Validation to me, but rather a Usability enhancement.
Mark Seemann
+1  A: 

Entities have both data and behavior, so letting your entities ensure their invariants is the way to go IMHO. Else, you might end up with an anemic domain model [Fowler].

If your context allows you to enforce the rules in the setters as Mark Seemann suggests, it would be great since you don't have all the "IsValid" and/or "BrokenRules" logic in your model.

I've been in two contexts where we found ourselves needing the aforementioned solution though:

  1. A classic response/request web solution where the web page displays all the broken rules of an entity upon failing save.

  2. The model is read from a database which is updated externally (hence it's not impossible for the entity to be invalid despite the setter logic, unless you let your ORM use the setters, but the whole point for us was to find out about the validity).

Martin R-L