BDD/DDD Where to put specifications for basic entity validation?

家住魔仙堡 提交于 2019-12-07 14:26:39

问题


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:


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.




回答2:


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).



来源:https://stackoverflow.com/questions/1510715/bdd-ddd-where-to-put-specifications-for-basic-entity-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!