52 likes
路
556 reads
7 comments
Interesting read!
very well written 馃憤.. thanks for sharing
Great content, and welcome to Hashnode!
Hey Piotr, great stuff!
However, I would like to disagree with some points of your article and maybe start a discussion :)
- In my opinion what is presented as a Domain Service is actually an Application Service. It is true that when you have logic corresponding to more than one aggregate you should have a Domain Service. But it only refers to domain logic. Using repositories, making external calls, and dispatching events are rather application logic where you orchestrate your business process (I have written about it here jorzel.hashnode.dev/different-types-of-app… if you are interested, also recommend this nice article: enterprisecraftsmanship.com/posts/domain-v…).
- I think that your example of aggregate can be a little bit misleading. The purpose of the aggregate is to perform a change preserving consistency. However, in your example, there is no rule that is forcing you to put
add_order
logic intoCustomer
. What invariants relating toCustomer
are protected by this aggregate?
Hello, Jaros艂aw! Many thanks for your feedback! I appreciate you taking the time to look over everything and pick up something to tackle.
I believe both of your conclusions stem from the fact that I attempted to make this article shorter - even today, I consider it to be very lengthy. As a result, certain ideas may not be described as thoroughly as I would want.
I definitely intended to illustrate a domain service here; the fact that it is used so "directly" in the final example may be a little deceptive, but I believed that building any extra presentation layer would add unneeded complexity. I also agree that an application service serves as an orchestrator for multiple domain processes, including some external calls. But, given the domain service deals with aggregates and other entities, I believe it should use a repository and dispatch domain events.
In terms of the aggregate, the major point I wanted to make is that the 'Customer' is actually a 'Person' (due to the O2O relationship) who stores the orders. To avoid overcomplicating the example, the only invariant that this aggregate regulates is the total value of all orders. With the aggregate in place, the most crucial feature I wanted to demonstrate is how the full aggregate is committed at once in the repository - as you indicated, to maintain consistency. If you think that's not enough about the aggregate, then you might be right - won't argue about that 馃檪
Perhaps if I went into more detail on a few subjects, some of them might appear better. Nonetheless, in general, I'm still really glad if a reader read the post, decided "it's not enough," and reached out for one of the sources recommended.
In any case, huuuge thanks for the excellent points! The articles on your blog that mention books I've read in the past, like "Atomic Habits" or "Deep Work," are looking really interesting. I'll certainly give it a look sometime!