Reputation: 632
My domain entity often looks like this:
class {
rename(string $name): void {
if ($this->name === $name)
return;
$this->name = $name;
$this->recordEvent(new CategoryRenamed($this->id, $this->name));
}
changeDescription(string $description): void {
if ($this->description === $description)
return;
$this->description = $description;
$this->recordEvent(new DescriptionChanged($this->id, $this->description));
}
changeColor(Color $color): void {
if ($this->color->equals($color))
return;
$this->color = $color;
$this->recordEvent(new ColorChanged($this->id, $this->color));
}
}
I have few questions:
Do I have to check that property changed and just return if it didn't?
My goal is to reduce unnecessary code invocations (including database). And also some services may be subscribed to events, so every time event raised - every listeners execute their logic
Do I have to test that event doesn't occur if property didn't change?
At the moment I have two tests for each method: one that event occurs if something changed, second - that event doesn't occur if property didn't change.
What is the best practice for domain entities? And why I should do this?
Upvotes: 1
Views: 46
Reputation: 57307
Do I have to check that property changed and just return if it didn't?
In some domains, yes - that's appropriate.
In other domains, you may indeed need to keep track of command invocations that don't do anything. For example:
changeColor(Color $color): void {
if ($this->color->equals($color))
$this->recordEvent(new ColorPreserved($this->id, $this->color));
else {
$this->color = $color;
$this->recordEvent(new ColorChanged($this->id, $this->color));
}
}
In my experience, the DDD literature is poor when it comes to discussing cases where branching logic inside the model needs to be surfaced to the rest of your implementation. Some of that comes from the constraint that "commands" must return void, which is an idea that traces back to Bertrand Meyer.
Do I have to test that event doesn't occur if property didn't change?
What are the costs of writing / supporting these tests? What are the benefits?
The main benefit of having tests is to detect faults that would otherwise be missed (but remember, the primary defense against faults is... not making mistakes). This is especially true if a change in behavior here could end up breaking code somewhere else.
There are some secondary benefits in tests as a form of documentation, to help onboard the next developer (which might be future-you, having forgotten some of what you know today).
Upvotes: 0