1

On one hand, the invariants should be protected (To make invalid states impossible early and preferably at compile time rather than run time), and on the other hand, passing domain knowledge out of the domain is wrong.

On one hand, the value objects protect our domain invariants at first place, on the other hand using them as commands or as it's properties equals passing domain knowledge around.

The only solution for both protecting the invariants, and avoiding the domain knowledge from leaking the domain boundary (encapsulating the domain model), seems to wrap the aggregates in a command-to-value-object-mapper.

I'm using CQRS along with ES.

Is it ok to have a wrapper as a command-to-value-object-mapper around my aggregate roots? Is there any other solution?

  • "the value objects protect our domain invariants at first place" : what do you mean? Invariants are primarily protected by aggregate roots, not VO's. – guillaume31 Jul 23 '18 at 9:14
0

On one hand, the value objects protect our domain invariants at first place, on the other hand using them as commands or as it's properties equals passing domain knowledge around.

Nothing in DDD says that you shouldn't pass domain knowledge around. Quite the contrary - the Ubiquitous Language means that domain knowledge will be everywhere from front end to repositories.

You might mean domain logic instead.

Commands don't include domain logic. They are dumb data structures that describe user intention and the data associated. They don't implement anything. So if you use commands properly, you're good to go - no domain logic leakage.

  • You seem like have not gotten the main question. Let me change its title to make it clearer. – Mohsen Jul 23 '18 at 9:05
  • Now I'm confused. The new title mentions command handlers while the question body does not. And your title is in the affirmative form. Interrogative form would be more appropriate. – guillaume31 Jul 23 '18 at 9:12
  • Thx. I fixed the form, the question would be sth like: Can command handlers be separated from aggregate roots and value objects be composed at the command handlers in CQRS? but it would be too long. And the body is supporting it. Find the phrase: wrap the aggregates in a command-to-value-object-mapper from the page. – Mohsen Jul 23 '18 at 9:17
  • Sorry, I can't make any sense of that question except that you're making a big big confusion between Commands, Command Handlers and Value Objects. – guillaume31 Jul 23 '18 at 9:21
  • In addition to a big confusion between knowledge and logic. – guillaume31 Jul 23 '18 at 9:21
1

On one hand, the value objects protect our domain invariants at first place, on the other hand using them as commands or as it's properties equals passing domain knowledge around.

I do not agree with this. You may do whatever you need with your Commands and Events, even store them if you like. They are immutable and do not contain domain knowledge. They represent the intent and the fact.

Passing around domain knowledge could mean to have the domain code/logic spread around in layers other than the domain, i.e. in Application or Infrastructure services, which is indeed bad.

The solution is to keep the domain code that handles invariants (the domain logic) inside the Aggregates (this includes the Aggregate root, the nested Entities and the Value objects). BTW, you may pass around the Value objects also, as arguments to method calls; they are also immutable, as an indication that modifying them is not allowed or is pointless.

Is it ok to have a wrapper as a command-to-value-object-mapper around my aggregate roots? Is there any other solution?

No, it is pointless. Also, transforming them into something else would make them to loose the intent, their most important aspect.

  • 1
    Commands are messages kind of like immutable DTOs ,but value objects are objects. Objects defined as data+ behaviour. – Mohsen Jul 21 '18 at 19:43
  • @Mohsen Commands have data and behavior: they contain basic validation like non-null checking or minimum or maximum value checking. – Constantin Galbenu Jul 21 '18 at 19:45
  • 1
    The value objects are rich domain behaviour representative, and the only thing I find in them that is same as commands is their immutability. Sometimes yau may use the value objct api like a builder which build itself step by step, but since you should be able to stor the commands, and the behaviour is not serializable ... – Mohsen Jul 21 '18 at 19:52
  • 1
    @Mohsen validation behavior is still behavior. And sometime Value objects do not have so rich behavior as you may think. Sometimes all they bring is only high cohesion between some properties, at least at the begining. Passing Commands and Events around keeps the things simple and reduces the accidental complexity. With a good framework you could have only the Domain layer and a little infrastructure. The framework would unserialize commands directly from a HTTP body and Events from the Event store. – Constantin Galbenu Jul 21 '18 at 20:06
  • 1
    Thabk you. Nice discussion. – Mohsen Jul 21 '18 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.