domain driven design - DDD Invariants Business Rules and Validation -
i looking advice on add validation rules domain entities, , best practices implementation. did search , did not find looking for, or missed it.
i know recommended way validating properties not null, in range, or length, etc... have seen several ways using isvalid() , other discussions enforcing in constructor entity never in invalid state, or using preprocessing , postprocessing, , others using fluentvalidation api, how invariants impact dry , srp.
can give me example of put these sorts of checks, when using app service, bounded context, domain service, aggregate root, entity layering. go, , best approach?
thanks.
when modeling domain entity, best consider real-world implications. let's dealing employee
entity.
employees need name
we know in real-world employee must have name. impossible employee not have name. in other words, 1 cannot 'construct' employee without specifying name. so, use parameterised constructors! know employees name cannot change - prevent happening creating private setter. using .net type system verify employee strong form of validation.
public string name { get; private set; } public employee(string name) { name = name; }
valid names have rules
now starts interesting. name has rules. let's take simplistic route , assume valid name 1 not null or empty. in code example above, following business rule not validated against. @ point, can still create invalid employees! let's prevent ever occurring amending our setter:
public string name { { return name; } private set { if (string.isnullorwhitespace(value)) { throw new argumentoutofrangeexception("value", "employee name cannot empty value"); } name = value; } }
personally prefer have logic in private setter in constructor. setter not invisible. entity can still change it, , need ensure validity. also, throw exceptions!
what exposing form of isvalid()
method?
take above employee
entity. , how isvalid()
method work?
would allow invalid employee created , expect developer check it's validity isvalid()
check? weak design - before know it, nameless employees going cruising around system causing havoc.
but perhaps expose name validation logic?
we don't want catch exceptions control flow. exceptions catastrophic system failure. don't want duplicate these validation rules in our codebase. so, perhaps exposing validation logic isn't such bad idea (but still not greatest!).
what provide static isvalidname(string)
method:
public static bool isvalidname(string name) { return (string.isnullorwhitespace(value)) }
our property change somewhat:
public string name { { return name; } private set { if (!employee.isvalidname(value)) { throw new argumentoutofrangeexception("value", "employee name cannot empty value"); } name = value; } }
but there fishy design...
we starting spawn validation methods individual properties of our entity. if property has kinds of rules , behavior attached it, perhaps sign can create value object it!
public personname : iequatable<personname> { public string name { { return name; } private set { if (!personname.isvalid(value)) { throw new argumentoutofrangeexception("value", "person name cannot empty value"); } name = value; } } private personname(string name) { name = name; } public static personname from(string name) { return new personname(name); } public static bool isvalid(string name) { return !string.isnullorwhitespace(value); } // don't forget override .equals }
now our employee
entity can simplified (i have excluded null reference check):
public employee { public personname name { get; private set; } public employee(personname name) { name = name; } }
our client code can this:
if(personname.isvalid(name)) { employee = new employee(personname.from(name)); } else { // send validation message user or }
so have done here?
we have ensured our domain model consistent. extremely important. invalid entity cannot created. in addition, have used value objects provide further 'richness'. personname
has given client code more control , more power , has simplified employee
.
Comments
Post a Comment