Based on what we have discussed so far in this book lets lay down the various building blocks we have identified, along with the name of layers in which they belong.
Presentation Layer: Controller, View, View Model
Application Layer: Application Service, Request Validator, Application Contract
Domain Layer: Domain Service, Domain Model, Repository
Infrastructure Layer: Record Object, ORM
The layers that we see here are same as in the domain driven design book. Here we have also called out the building blocks in a layer so that we can look in detail their responsibilities. In order to under them, we would use negative examples, that is what a block should not do. Your application need not have all of above building blocks as we have discussed in various parts of this book. But for the sake of simplicity let's assume that you have all these blocks. These layers are which are stacked on top of each other and from the programming perspective only the layer immediately below is accessible to any layer.
Repository (from DDD: A mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects)
Repository should not have any logic other than how to do above. This includes filtering,
Weaved in Repository
When we use hibernate we might overlook the fact that runtime behavior of the entities is more than what we get to see from the code. It weaves in a clever code (aka AOP) which facilitates lazy loading. If we look at the entity code at runtime, it would entail repository (database calls) from within in the entity. This compile time separation of aspect code and domain code is quite useful. This separation principle can be continued when we want to do lazy loading when using Record Objects or Remote Service Repository. In other words entities code should not reference repository or infrastructure layer, not even if it can be injected as dependency.
<<Code Sample>>
Scenario: An application service wants to reuse functionality provided by another application service
There are two ways to do this. In first approach the application service simply calls the other one. In the second approach the caller calls the domain service which is used internally by the callee application service, instead of invoking it directly.
Building blocks of an application (server side) and its responsibilities and not its responsibilities. Repository Doesn't have business logic. Doesn't modify loaded data in any way. Hand written aspects. Should not know about contract.Takes only domain/value objects in its method. DataMapper No business logic. Use of visitor pattern to hide internal structure of domain model. No data Update when mapping. DomainObject Mapping to fields. Logic in getters/setters and also mapped to database. Doesn't expose internal structure. Contract Do not pass any data in request which might already be present on the server, unless you have might changed the data. No contract reuse across different operations. No modification the request contract object on the server. WebService Knows only about mapper, service, contract validator and contract. Fewer service operation, one webservice performing supporting multiple operations. Webservice not per entity but rather on aggregates. One request parameter and response object.