Chris,

Thanks for your response.

It sounds like the "exposed domain model" is what we are using right now. Our current DAOs are what are called Repositories in EDM. I am investigating moving away from it because of the clear lack of layers, which is what brought me to consider DTO's etc. I'm not a big fan of building classes just for the sake of it, so I decided to ask here how other deal with this.

In your apps, how do you deal with transactions? Since you expose your domain models, and have OSIV, where do you begin and commit a transaction?

Also, how do you define your internal api contract?
E.g. in our case we have an Order entity and a Customer entity. Let's say we have a business rule that says the total amount of outstanding orders has to be within the Customers credit limit (e.g. a number on the customer entity). If we expose the repository directly to the view (wicket), this means that it's possible to simple whip up a new Invoice entity, and call repository.persist(invoice), thus bypassing any checks. Since we have a lot (a lot!) of orders, we don't access them as a list on the customer, but have a method on the repository getOutstandingAmountForCustomer(Customer). Since we don't inject repositories or services into our entities, this means the developer always has to go through a service layer when saving an invoice.
How do you deal with such situations?

We cannot remove the persist() method from our repository, since we need to save the invoice at some point. I guess it's the fact that "sometimes you go through the service layer, sometimes you don't" part that bugs me.

Again, thanks for taking the time to bear with me :-)

Op 12-2-2012 21:42, schreef Chris Colman:
It sounds like you have a lot of layers/scaffolding (=high maintenance)
in your design.

The "exposed domain model" pattern was created to avoid all those extra
layers (especially DAOs and DTOs) in recognition of the fact that for
most applications they *feel* redundant and *seem* like code
duplication.

I understand the puritan goals that bring about the adoption of DTOs but
IMHO introducing them forms a slippery slope to "productivity
impedance".

We adopted the Exposed Domain Model (EDM) pattern with "Open
[Session|PersistenceManager] In View" many years ago and haven't created
a DAO or DTO since - and development has been easier, faster and more
maintainable since.

EDM still does provide for Respositories (object search, looks ups,
etc., - where your queries reside) and Services (where you orchestrate
non trivial model changes, updates) but for the most part if the UI is
simply CRUDing a model object we expose that model object and let it
call the setters and getters directly.

We even allow some trivial persistent objects to be instantiated
directly by the UI where that is appropriate. With 'persistence by
reachability' (we use JDO - JPA might also have this) it's not even
necessary to call persist() on the newly constructed instances if they
are reachable by at least one already persisted object.

In certain cases where instantiation of an object graph must be
orchestrated according to some business rules or some constraints
implicit in the model we do either of the following:

1. make the domain class' constructors private and force instantiation
to take place via a static method on the particular class.

2. make the domain class' constructors protected and force instantiation
to take place via a Service provided for the package in which the new
class exists.

It's been working flawlessly for us and our domain model now has over
300 persistent classes. I doubt we would have been able to grow it this
fast if we had the extra development burden of developing and creating
DAO and DTO classes on the way. Also the code base would probably be
close to double what it is today.

Having let our hair down this much we must state that we still are 100%
puritan when it comes to separation of Model and Presentation layer. The
model itself has ZERO dependencies on any UI code and can be compiled
completely independently of the UI.

-----Original Message-----
From: James Carman [mailto:jcar...@carmanconsulting.com]
Sent: Monday, 13 February 2012 4:40 AM
To: users@wicket.apache.org
Subject: Re: Architectural question

Well setters/getters somewhat go against ddd.  We just have to figure
out
what works for us.  It's all about finding what gets the job done most
effectively.
On Feb 12, 2012 10:45 AM, "Bas Gooren"<b...@iswd.nl>  wrote:

We already use OSIV, thanks to guice-persist.
This means the read-side of things is rather trivial, and that the
service
and dao layers do need to be aware of the exact data the view needs
(since
lazy loading is possible).

With regard to the write-side of things: we do what you do (call
update
explicitly) right now.

Suppose you are using DDD in a project, how would you go about
constructing and populating a new object? Without DDD my entities
were
mere
containers for data with some validation and JPA annotations. So it
was
simply a matter of creating a Model which wraps a "new Customer", and
wicket pushing its fields to that customer object.

However, when applying DDD, that Customer is no longer a simple
container,
but a business object. Having wicket push changes directly to fields
(those
fields may even be private-access only, without setters) seems to go
against DDD fashion.

So I feel it would be better to create a DTO for a certain view (e.g.
NewCustomerDTO for a CreateCustomerPanel), and putting all validation
annotations on the DTO, too. When it's time to persist the new
customer,
the service layer simply creates a new customer and copies all fields
from
the DTO.

But then again, maybe this is overcomplicating things. DDD seems like
a
good match for most of my projects though, and I'd like to be able to
properly integrate my domain objects with wicket.

Op 12-2-2012 15:17, schreef James Carman:

I just use open session in view.  You can still retrieve stuff
outside a
transaction.  I explicitly call update to persist.
On Feb 12, 2012 7:54 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