microsoftarchive / cqrs-journey

Microsoft patterns & pratices CQRS Journey sample application
http://cqrsjourney.github.com/
Other
1.38k stars 460 forks source link

Have you considered making SeatsAvailability a Domain Service? #350

Closed Burtsev-Alexey closed 12 years ago

Burtsev-Alexey commented 12 years ago

I think SeatsAvailability should be a domain service instead of Aggregate.

It doesn't contain state. The two fields it has: remainingSeats, pendingReservations are both calculated, based on Orders. RemainingSeats = totalSeats - (you logic here) for example Reserved+Confirmed. PendingReservations = Orders.Where(State == pending).Sum(Seats).

It perfectly fits a difinition of Domain Service http://domaindrivendesign.org/node/125

Definition: A Service is an operation offered as an interface that stands alone in the model, with no encapsulated state.

Problem: Some concepts from the domain aren't natural to model as objects. Forcing the required domain functionality to be the responsibility of an Entity or Value Object either distorts the definition of a model-based object or adds meaningless artificial objects.

Solution: When a significant process or transformation in the domain is not a natural responsibility of an Entity or Value Object, add an operation to the model as a standalone interface declared as a Service. Define the interface in terms of the language of the model and make sure the operation name is part of the Ubiquitous Language. Make the Service stateless.

kzu commented 12 years ago

Interesting suggestion!

Now, as Orders are event-source, there isn't an easy way to do Orders.Where(State == pending).Sum(Seats)....

So, would you solve that by having a domain service that takes a dependency on the read-model for the other? (which can potentially provide that kind of querying capability?)

/kzu

Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471

On Sun, May 6, 2012 at 10:25 AM, Burtsev Aleksey < reply@reply.github.com

wrote:

I think SeatsAvailability should be a domain service instead of Aggregate.

It doesn't contain state. The two fields it has: remainingSeats, pendingReservations are both calculated, based on Orders. RemainingSeats = totalSeats - (you logic here) for example Reserved+Confirmed. PendingReservations = Orders.Where(State == pending).Sum(Seats).

It perfectly fits a difinition of Domain Service http://domaindrivendesign.org/node/125

Definition: A Service is an operation offered as an interface that stands alone in the model, with no encapsulated state.

Problem: Some concepts from the domain aren't natural to model as objects. Forcing the required domain functionality to be the responsibility of an Entity or Value Object either distorts the definition of a model-based object or adds meaningless artificial objects.

Solution: When a significant process or transformation in the domain is not a natural responsibility of an Entity or Value Object, add an operation to the model as a standalone interface declared as a Service. Define the interface in terms of the language of the model and make sure the operation name is part of the Ubiquitous Language. Make the Service stateless.


Reply to this email directly or view it on GitHub: https://github.com/mspnp/cqrs-journey-code/issues/350

kzu commented 12 years ago

We're not following Udi's specifically or exclusively.

/kzu

Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471

On Mon, May 7, 2012 at 12:42 AM, Burtsev Alexey < reply@reply.github.com

wrote:

Well how you solve this depends on your style.

If you follow Udi Dahan CQRS style, then you should not have Domain Services, your Domain Services are commands handlers. Command handlers must not use reporting database. I would call this "Tell, do not ask."

I solve such problems in completely different manner. I use my own architecture style based on "classic DDD" (as discribed by Eric Evans), Event Sourcing and CQS (as described by Martin Fawler).

Well, I actually already regret that I said this, probably I will only confuse you with my vision on how this should be done. And I'm actually very interested in how you will solve many problems that occure while following Udi's CQRS style architecture.


Reply to this email directly or view it on GitHub: https://github.com/mspnp/cqrs-journey-code/issues/350#issuecomment-5545218