Alexey Shimansky
Alexey Shimansky

Reputation: 632

Should I check equity value in domain entity to prevent unnecessary events in DDD?

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:

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

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

Answers (1)

VoiceOfUnreason
VoiceOfUnreason

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

Related Questions