Application service parameters / return types

I usually find myself leaning towards approach one, using commands and queries.

Here is a snippet of a blog post I'm publishing this weekend.

Commands help you in supporting the ubiquitous language by explicitly capturing user intent at the boundaries of your system - think use cases. They serve as a layer over your domain, decoupling the inside from the outside, allowing you to gradually introduce concepts on the inside, without breaking the outside. The command executor gives you a nice pipeline you can take advantage of to centralize security, performance metrics, logging, session management and so on. And also, if that's your thing - commands can be serialized dealt with asynchronously.

You can find an example of this on my blog; http://www.jefclaes.be/2013/01/separating-command-data-from-logic-and.html.

In respect to your concerns regarding validation, keep in mind that having validation duplicated isn't horrible; http://gorodinski.com/blog/2012/05/19/validation-in-domain-driven-design-ddd/.


+1

I prefer a mixed solution.

1) I use domain objects as arguments, but limited to ValueObject s. I believe the lifecycle of Entity s should be managed carefully, and most of the time the view doesn't have enough value to populate the whole Entity except very simple CRUD applications. I saw many times that some developers init Entity by constructor carelessly and populate them with only part of the fields they required for a particular function, this makes it very easy to introduce bugs for NullPointerException and the poor guy who is assigned to fix the issue has to search across tens of methods to find where the Entity given was created. Entity s are retrieved from Repository or created by Factory in my projects.

Sometimes I use some form objects as parameter for simplicity.

2) I use a mvc Controller to convert domain objects returned by application service to ViewAdapter(a componenet decouples domain models from ui), sometimes dettach work need to be done here.

3) I use a Facade only when the application service need to be exposed via remote procedure call like web-service. Dto s are used as arguments and return types in this case and the Facade is responsible for converting DTO and Domain Model.

4) Validation is awkward if the application service need to be exposed to both web view and remote procedure call. This causes duplicate validation implemented on both form objects and Dtos. I validate simple constraints only(Not null, length to name a few, business rules are validated by domain objects programmatically) because I haven't found a perfect solution yet.

Hope this helps and if there are better solutions do let me know please.

Update1:

1) I have to confess that I'm not a guru in this area and I'm trying to find a good solution as well. So sometimes there is some inconsistency in my current solution such as the form bean you mentioned in comment. Sometimes we take some form bean as Command and place some domain logic in it, so these command belong to Domain Layer in this case.

2) Transaction boundary is on the application service. Technically, The domain object could be modified out of the boundary inadvertently. We cover this by team discipline and code review.