문제

This is a follow up to another question: Bypassing Aggregate Root.

The author of this question asked if bypassing an aggregate root was acceptable in his example. I have the same question, but for a different use case.

Our web application has a backoffice in which we can edit all of the items that belong to an aggregate root:

  • Products (aggregate root)
  • Options
  • Option items

etc.

Because a product is not created with all of its options in a batch, we edit each entity in the aggregate root, one by one, in a separate screen. As we are in a stateless system, we need to uniquely identify the entity we want to work on in URL parameters. This means that we will, for example, fetch & edit an option based on its id, rather than browsing from the root.

IMHO, it makes more sense to have a repository for each of them, and just do:

$optionRepository->find($optionId);

Rather than something like:

foreach ($product->options as $option) {
    if ($option->id == $optionId) {
        // ok, we finally found it, we can now work on it
        // ...
        break;
    }
}

Is that breaking the concept of aggregate roots from domain-driven design? In that case, I would be very grateful to learn the correct way to do that.

도움이 되었습니까?

해결책

It is breaking the aggregate root concept. There is not a "correct" way to do it. Either you decide to just ignore aggregate root rules and access the objects directly, or you decide to follow aggregate rules and you traverse to the object from the root. You can do it one way or the other, there really is not anything else possible, so there is not any sort of third alternative that represents a "correct" way to both access an object directly and still obey aggregate root rules.

It is a matter of choice. I personally would break aggregate root rules if there is some sort of compelling reason to do so. Unless the list is huge, what you are suggesting is probably mostly convenient. Is it really even that convenient? You have to create and maintain another repository etc etc.

The thing is once you create that Options Repository, people are going to use it. Wherever and whenever. And then there is the next scenario, surely you have other similar situations. Let's create another repository. We did it there why not here too? Pretty soon you might as well have a repository for every object, that is eventually what will happen anyway.

Not saying that is a good thing or a bad thing. I've worked on apps before where there were no formal aggregate roots. All I am saying is it is not really a middle ground sort of thing. If you are going to use them at all, you kind of have to be a stickler about aggregate root rules You either recognize aggregate roots and follow the rules at all times (except maybe under extremely exceptional circumstances, which what you have described is not), or you might as well not have them at all.

Consistency is probably as important. I would either observe the aggregate roots or do away with the potential burden they can represent altogether.

다른 팁

If you will not load entities from aggregate root, you will not be able to enforce aggregate invariants (like Product must not have more than one option of type A). As result, your data can be not consistent.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top