DDD teaches us to build our classes like their real-world prototypes.
So instead of using setters
job = new Job
job.person = person
job.since = time.Now()
job.title = title
we define well-named methods in our aggregation root
job = person.promote(title, /** since=time.Now() **/)
Now the tricky part
Assume we have an UI for an HR where he/she enters a new title
via the HTML form and makes a typo like "prgrammer" (Of course in real application there'd be a select list, but here we have a text input), or selects a wrong date (like default today)
Now we have a problem. There are no typos in real world. Our John Doe is definitely a "programmer" and never a "prgrammer"
How do we fix this typo in our domain model?
Our Person
has just promote
, demote
, fire
, etc. methods, which reflect the HR domain model.
We could cheat a little bit and change the Job
record directly, but now we have a Job.setTitle
method, that doesn't reflect our domain model and also, setters are evil, you know.
That may look a little "academic", but that really bugs me when I try to build a good domain model for a complex application
Another side of DDD is invariants - "always valid" entity. And when you try to break this invariant (some rule) you must stop execution and say "loudly" adout this (throw exception). So, you need to have a list of valid titles and when you try to change title (does not matter how) to invalid state, you must throw some usefull exception.
To "fix" typo situations you must separate operations in your domain promote
is one operation (it may check something, sent contratulation email :) and so on). And edit
operation - just to edit some properties. So, the differenece is in logic of operations. You can't call promote
without some preconditions (for example, required experience of worker), but you can call edit
and fix worker's name because of type.
And usually this operations are separated between different users: only HR's can promote
but a worker can edit
his name, if it's wrong.
This solution is very complicated for such example, but it's always with DDD.
The main concept - separate operations. Each one with their own conditions, permissions, rules.
A question about invariants (rules).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With