I have read this and it makes me think twice...:
"Avoid unit of work pattern. Aggregate roots should define transaction boundaries."
Why should someone avoid the UOW pattern applying domain driven design?
I have read this and it makes me think twice...:
"Avoid unit of work pattern. Aggregate roots should define transaction boundaries."
Why should someone avoid the UOW pattern applying domain driven design?
(Before my post I recommend to read this chapter of "Implementing Domain-Driven Design" book by V. Vernon. It can help to get close with aggregates and contain long answer on your question.)
In a properly designed system one command changes one aggregate at a time, every aggregate has boundaries which defined by invariants in aggregate root. So when you do any changes on aggregate, invariants are checked and changes are applied (or not) in one transaction. It's transaction consistency. Do you need to use Unit of Work here? Don't think so.
But quite often we are in situation when more then one aggregate need to be changed at one time. Transactions become larger, they touch more then one part of a system and we talk about eventual consistency. UoW is a good helper in this case.
As it has been mentioned with no context it's hard to guess what author was thinking, but I suppose he told about transaction consistency case. In distributed system you will need to use something like UoW to provide eventual consistency to a system.
Basically, according to M. Fowler, the UoW is "just" a smart persistence tool (however complex this task may be). So IMHO there is no intrinsic incompatibility with the DDD approach, which gives guidelines more about the "spirit" of your doman modeling than about technical tools.
With no context, it's hard to tell what the author of the citation was thinking; but maybe he wrote this because when using UoW, it is often difficult to enable your entities to manage their own lifecycle (as well as others'), typically with persistence and transactional behaviour.
As a matter of fact, it is possible to use the UoW pattern in a DDD-style applications with AOP. With this kind of tools, it becomes possible to keep the DDD spirit, with entity-centric, business-capable domain model(s), while leveraging complex yet business-orthogonal mechanisms to achieve proper transactional persistence.
Typically, in the Java world, you may use in your DDD app:
These give DDD-ready (and heavily-@nnotated ;]) entities.
First up, an aggregate is an object for holding a set of loading entities, for a command to be applied to.
A "Unit of Work" is basically an on-the-fly aggregate, allowing a single transactional update to a set of entities, without having to explicitly define in code an aggregate to do this.
This comes at the cost of not having an explicit Aggregate class on which to put mutation methods which protect your invariants.
The top voted answer contains:
In a properly designed system one command changes one aggregate at a time, every aggregate has boundaries which defined by invariants in aggregate root. ...
But quite often we are in situation when more then one aggregate need to be changed at one time. Transactions become larger, they touch more then one part of a system and we talk about eventual consistency. UoW is a good helper in this case.
This is nonsensical, because, by definition, an aggregate is the set of stuff needed for a transaction. If you find that you "need entities from two different aggregates", then actually what you need is to "define am additional aggregate which holds references to the entities required".
I think what the answer is trying to say is, "quite often we are in situation when more then one aggregate data on two different stores, which can't be updated in a single transaction, and therefore can't be added to a single aggregate need to be changed at one time. Transactions become larger, they touch more then one part of a system and we talk about eventual consistency. UoW is a good helper in this case."
AccountAggregate
is an aggregate for the command CreateAccountCommand
. If I want to transfer money, does it mean that I need to create another aggregate TranferMoneyAggregate
which will contain two accounts and holds transactional consistency? Or fetching two separate AccountAggregate
aggregates and putting transfer money logic into domain service is a better idea? –
Einsteinium TransferMoneyAggregate
contains two entities for both accounts what entity will be an aggregate root? Or aggregate root is TransferMoneyAggregate
itself? And another question, if I need to change some property on Account
, does it mean that Account
becomes an aggregate too in this case? –
Einsteinium Order
, Car
, Backlog
(nouns), where TransferMoneyAggregate
sounds like action. It confuses me with use-cases. What is the point of use-cases then? Or am I missing something? –
Einsteinium TransferMoneyAggregate
was your name, not mine! EntitiesRequiredForAMoneyTransferAggregate
, TwoAccountsAggregate
or any other name you like would do. –
Wagner © 2022 - 2024 — McMap. All rights reserved.