we use a pretty thin architecture described here:

https://www.42lines.net/2011/11/29/leveraging-conversations/
https://www.42lines.net/2011/12/01/simplifying-non-trivial-user-workflows-with-conversations/

this allows us to expose our domain model to the UI but control when
and where the updates actually happen.

together with https://github.com/42Lines/wicket-bean-validation you
can put your validation into your setters and get closer to the "true"
ddd way of doing things. also, setters can have sideeffects on the
subgraph of the entity and the UI will reflect them as well - all
without having to persist anything into the database in a "half-done"
state and without having to capture the complete state in a dto.

-igor

On Sun, Feb 12, 2012 at 4:53 AM, Bas Gooren <b...@iswd.nl> wrote:
> Hi All,
>
> I have an architectural question about wicket, DDD and the service layer.
>
> Let's say we have a simple JPA entity (Customer), and a few simple CRUDL
> screens.
> For database access, we have a DAO layer (CustomerDao) which delegates to an
> EntityManager, and provides some convenience methods for searching.
> We also like to have clear boundaries, so we have a thin service layer which
> wraps persist() and delete() calls in a transaction before forwarding them
> to the DAO layer (@Transactional, as provided by guice-persist).
>
> A wicket model fetches one or more customers (by id or by running a search),
> and attaches to a form. In the form we use PropertyModels which push their
> changes to the entity, and in onSubmit() we call service.persist(entity).
> This means that the actual changes to the model happen outside of the
> transaction (in wicket code), and within the transaction (/service layer) we
> merely call persist() and flush().
>
> Then parts of the app need something a bit more advanced, so we decide to
> apply parts of DDD and put logic where it belongs (on the domain models).
> However, some logic coordinates multiple models, so we add a domain- or
> application-service for that.
> The good thing about DDD is that it's a lot more clear what happens
> (intent). We now realize that having a persist() method on a entity-based
> service now looks like a bit of a code smell, since it does not capture
> intent at all. Also, since the changes to the model happen in wicket, before
> the service layer is called, I feel that the service layer is not doing
> anything to act as a boundary. We might as well mark the persist() method on
> our daos @transactional and remove the service layer.
>
> The only clean way to fix this seems to be either:
> (a) using DTO's so the UI/wicket is not actually modifying domain entities
>    upside: the state of the domain is not modified by wicket itself
>    downside: duplication of models (actual model + DTO);
>    downside: validation is currently set-up in wicket by scanning fields for
> validation annotations, so we would need to duplicate those on the DTO?
>
> (b) using a concept from CQRS: sending commands to the domain through a bus.
> This clearly and cleanly defines the intent and captures the exact change.
>    upside: the state of the domain is not modified by wicket itself
>    downside: likely overkill for what we are trying to achieve; lot of extra
> complexity
>
> (c) wrapping the entire request in a transaction
>    upside: easy to implement
>    downside: since anything in the request can fetch a dao, read some
> entities and modify them, this means we can lose track of what happens in a
> request;
>    downside: feels like moving backwards
>
> (d) simplify by removing thin services and, where necessary, putting more
> logic in the dao's
>    upside: simple api contract: want to save/update an entity? use the dao
> directly
>    downside: dao's contain logic which does not really belong there
>    downside: if at some point we really do need a service, the api contract
> becomes less clear: for X and Y you can use the dao, for Z you have to use a
> service
>
> (a) and (b) provide a way to capture a change and execute all of the change
> inside a transaction.
>
> So my question to the list is: what are your experiences with this? How do
> you deal with this in simple to moderately complex webapps?
>
> Thanks for reading!

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to