|
#1
|
|||
|
|||
|
I recently started reading the book "Domain driven design" and I would like to start a little discussion here about how to implemented a good layered design, especially input from people who also read the book.
Let me start by telling you that I also made the fault of making my domain model looking like the anemic model. I guess the influence of using EJB's inthe past was greater than I thought ... So to gain some more insight in the way a "good" domain model should be designed I started reading the book I mentioned above.So this is the architecture I had before () controller --- usecase --- service --- domain --- dao Now let me explain - Controller has the only responsability to put an get data from the screen / form. The controller gets his business data from a class in the use case layer, also the submission of data will be handled by that use case class. - Usecase is responsible for handling, like the name indicates, use case functionalities. It is actually a facade to hide multiple service activities behind one method. - Service layer handles everything what is beneed its layer, so it is responsible for crud operations and also for "service" operations. So it wraps multiple daos. Business logic and validation is handles by this layer - Dao has only crud operations, no validation, no logic, just orm mapping - Domain = anemic model ... no business logic So after reading (I'm only half way) I'm thinking of using architectures like controller ------------------- Usecase ------------------- service | repository ------- ----------- domain ---------- DAO ------------------- - So for now I would keep the concept of a use case layer., but instead of only accessing the service layer it can now also access the repository - The service layer has now only "service" functionality, so no explicit crud operations, so its responsability is now more clear. The service layer cannot call the dao directly for crud but should use the repository. - The crud operations on the database have been move to the repository which also handles the extra business / domain logic (This is the logic that was difficult to implement directly in the domain class, I'll come back on this later) - The dao still only holds the crud operations with orm mapping, no logic there. - The domain has now been extended by more logic in the methods, and extra classes in its package that do what is called in the book "specifications pattern". These specifications can be validation on the domain object or extra logic that was difficult to put directly into the domain layer. This extra logic now belongs all to the domain layer but will be handled by the repository. I'm still halfway in the book but seperating the service and repository seems a good idea, also making use of "specifications" is helping me put more logic in the domain layer that was before not 100% clear how to implement it directly into the domain object. So anyone else who read the book or wo has suggestions. I'll keep posting some thoughts on this topic when I found useful stuff in the book I also found an interesting article about a generic dao http://blog.hibernate.org/cgi-bin/bl.../08#genericdao, I still need to read it a second time to see if it can be used to really make a generic dao. For now I redefine my crud operations for each domain model, perhaps this can make it more easily. Grtz |
|
#2
|
|||
|
|||
|
Interesting post, I will be monitoring this thread and hope to contribute as well in the nearby future. I own the book as well, I am looking for time to start reading it. Therfore it is hard to comment on your post. But I am curious about the sepertion, of your service and repository layer. Sounds just like a special service to me, not really a seperate layer. Triggers me more to start reading the book :-)
|
|
#3
|
|||
|
|||
|
Jettro,
If that doesn't trigger you ... what about terms like anti-corruption layer ![]() Sounds hot doesn't it! About the seperation: What's in a name, I have a service "layer" and a repository "layer", I found that those two approaches belong side by side. Perhaps using the term "layer" is somewhat misleading.. perhaps pattern is a better name? So in that case I'll have a service and repository pattern Grtz |
|
#4
|
|||
|
|||
|
Recently I posted some remarks about the best way to handle modules in Spring. Instead of having 1 project its its always better to have multiple independent building blocks that you make use of when designing your application.
So following the "module' pattern from the book I guess that each module should represent an aggregation, clearly defined by its boundaries. The module name could be the for example the same as the root aggregation. I find the isolation of aggregations into modules very interesting when writing unit tests. When each module has its own Spring application context configuration, unit and module (integeration) tests really mark clear boundaries. Dividing the Spring context files up into service, repository, dao, ... makes it easier to test because for example unit testing my dao layer needs to load the hibernate session and dao bean from the context files. When you have 1 context file per module the test will take much longer because all the other beans must be loaded. Anyone out that has good experience with modules and a good way to unit test? |
|
#5
|
|||
|
|||
|
A few remarks about your design.
The Service layer doesn`t have the same scope as the gui/domain/dao layers. It is a sublayer in the domainlayer, that sits on top of the domain model. It is responsible for providing a clear api (a facade) but it also is very usable for adding transactions/security. The ServiceLayer is use-case oriented, so you don`t need an extra Use-case layer. Quote:
But I don`t see how the repository fits in. I know the 'Repository' from the 'Patterns of Enterprise Application Architecture', but they are for entity storage and with an or-mapper like hibernate, you don`t need to write them anymore. Last edited by Alarmnummer; Nov 7th, 2005 at 06:43 AM. |
|
#6
|
|||
|
|||
|
I agree with you that service layer is already use-case oriented, but in that way that its use case functionalities that it offers is limited to the underlying domain model. So in our application we have multiple services, when a creen action is taking, the logic behind is needs to perform multiple tasks, spread around in multiple services. So we created a use case layer that actually handles end user / end application use-cases scenarios. That way we hide the multiple services we need from the mvc controller. The mvc controller only has one dependency and that is our use case layer.
Secondly, about the seperation between the service and repository class. I was just reading through the book and keeping an open mind... so here some thoughts: - The DAO layer should not contain ANY business logic, its only responsability is to handle the ORM mapping - The domain model should hold as much as possible domain logic as possible. But sometimes to perform this domain logic, the model needs another dao or service and this is for the moment not simple to implement in Spring. I know they are working on it but it is still in the sandbox and I'm going to wait for it until it is in the releases. - So were do we put the logic, for now, that we cannot put in the domain model but that is part of the model? In the book these problems are handled by the Specifucation pattern. The specification pattern is used to solve problems like business logic validation, logic that cannot be placed in the domain model, ... . Can these business logic validations, and other specifications go in the service layer or not? I gues that all these kinds of specifications can go into the service layer for my part ... I as just looking at our service and dao and there were so many methods that were just delegating to the dao that I thought I was doing something wrong. - I see service as something on top of the domain, logic that realy does not belong t the domain model itself, I see specifications as part of the domain model so perhaps mixing these two in the same layer (services) is not best idea? I'm still reading the book, but for now I find the specification pattern nice to have, but still not sure about the repository layer, thats way I posted this message to see how people layer they apps. Feedback would be nice
|
|
#7
|
|||||||||
|
|||||||||
|
first a disclamer:
anything I say can`t be hold against me in a court of law. I`m also learning about this subject and I don`t have a lot of practical experience. So it could be that I`m wrong. Quote:
Quote:
Quote:
extra: It should contain logic, but you don`t need to place all logic into domain objects. Sometimes it is better to move the logic to a different class (in your domain layer). Quote:
Quote:
Quote:
Quote:
[edit] Quote:
Dead giveaway you speak dutch ![]() Quote:
Last edited by Alarmnummer; Nov 7th, 2005 at 08:21 AM. |
|
#8
|
|||
|
|||
|
Thanks for the reply
Could you explain by usng the small example below where you should put the business logic (the one that was not possible to put in the domain layer) because of dependecies): So what you are saying is that I should just use the following structure: Code:
Service ---> dao ---> database Code:
DomainObject update(DomainObject o) If you would drawn a layered diagram of your application, how would you draw it? Code:
service - dao -domain Code:
service dao domain Because perhaps I have a wrong view on what "layered" means? I always talked about a layer that is something that hides what is beneed. So a service hides that it is using some king of dao (hibernate/jdbc...) It would be great if you could tell me (with an example ... ) what the true meaning of a layer is, because the more I seem to work with "layered" design, to more I get confused ![]() But I'm learning
|
|
#9
|
||||||
|
||||||
|
Quote:
Code:
EmployeeService{
void fire(Employee employee){
Desk desk = employee.getDesk();
desk.clean();
employee.setStatus(FIRED);
employee.setSalary(0);
employee.setFiredDate(new Date());
employeeDao.save(employee);
}
}
Quote:
DomainLayer -> Data accesslayer -> Database the service layer only is a very small layer that is part of your domain layer. If you focus on the domain layer, you see: ServiceLayer : DomainLayer Quote:
Code:
class Employee{
void setSalary(int amount){
Validator validator = ... retrieve salary validator
validator.validate(amount);
_amount = amount;
}
}
![]() Quote:
Code:
class Employee{
void fire(){
Desk desk = getDesk();
desk.clean();
setStatus(FIRED);
setSalary(0);
setFiredDate(new Date());
employeeDao.save(employee); //this one is questionable.
}
}
Quote:
Quote:
Last edited by Alarmnummer; Nov 7th, 2005 at 09:09 AM. |
|
#10
|
|||
|
|||
|
Thanks for the reply,
I always thought when you were talking about the domain layer that you where talking about something above the domain model, but know I see that the term domain model and domain layer are the same... sometimes mixed terminologie can lead also to misunderstanding. Correct me if I'm wrong here ![]() Code:
class Employee{
void setSalary(int amount){
Validator validator = ... retrieve salary validator
validator.validate(amount);
_amount = amount;
}
}
Grtz |
![]() |
| Thread Tools | |
| Display Modes | |
|
|