|
#41
|
|||
|
|||
|
Sounds like a workable solution!
I would not add the ViewMode to the method signature of the service method, rather create specific beans where the correct ViewMode is set using the Spring context files. That we wa can indeed have the advantage of a DTO and have non project specific DTO's as a bonus, I can go with that! I think that the overhead of doing the cast is far from a problem, we are used of casting the Spring mvc command object so one more or less
|
|
#42
|
|||
|
|||
|
So actually this is just the Assembler pattern by Martin Fowler.
So for example we will have an interface that looks something like this: Code:
public interface MyService {
ViewObject getSomething(Integer id);
}
Code:
public interface ViewObjectAssembler {
ViewObject assemble(Object o);
}
Code:
public interface ViewObject {
}
Code:
public class MyCustomViewObject implements ViewObject {
}
Code:
public class MyServiceImpl implements MyService {
private ViewObjectAssembler assembler;
public ViewObject getSomething(Integer id) {
MyDomainObject do = ... retrieve the domain object;
return assembler.assemble(do);
}
}
Code:
public class MyCustomAssembler implements ViewObjectAssembler {
// handle the conversion
}
Code:
MyCustomViewObject x = (MyCustomViewObject) myService.getSomething(new Integer(5)); Comments are more then welcome
|
|
#43
|
|||
|
|||
|
I also have a problem with the name DTO. These DTO's are actually always view on domain models, so why not just call them ViewObjects? Then we'll have DomainObjects and ViewObjects.
|
|
#44
|
|||
|
|||
|
Quote:
This is a great thread BTW. Martin |
|
#45
|
|||
|
|||
|
Checkout DependencyInjectionInterceptorFactoryBean ... nice short name isn't it
|
|
#46
|
|||
|
|||
|
Quote:
I'm glad you take the ViewModes idea and turned it into something you can use. I haven't worked with Spring yet so I didn't consider the advantages of using it to resolve this. I just liked the discussion, but I will start checking out Spring though.
|
|
#47
|
|||
|
|||
|
Code:
employeeDao.save(employee); //this one is questionable. Code:
class Employee{
void fire(){
Desk desk = getDesk();
desk.clean();
setStatus(FIRED);
setSalary(0);
setFiredDate(new Date());
}
}
Code:
EmployeeService{
void fire(Employee employee){
employee.fire();
employeeDao.save(employee);
}
}
Validation Logic: Most of the validation logic is actually a pure business logic. As a such, it must be implemented in domain objects. Code:
class Employee{
void setSalary(int amount){
Validator validator = ... retrieve salary validator
validator.validate(amount);
_amount = amount;
}
}
Code:
class Employee{
void setSalary(int amount){
Validator validator = new Validator();
validator.validate(amount);
this.amount = amount;//let's follow java convention.
}
}
The people that are raving about DTO or something similar have probably never used something similar in real project. Otherwise, they would’ve still felt the pain. DTOs are defined by many people as anti-pattern but even if they aren’t, the only appropriate place for DTOs is when we have remoting, which should be avoided on the first place. Another, thing against DTO is the Don’t Repeat Yourself (DRY) principle. How many times you have to write the same code before you realize that something is wrong. In case, you wonder, try changing some property in the middle of a project (for exampe: we change the type from string to enumeration, or we change money property from double type to specific Money type). You have to change all of the objects that copy one to another. This is a lot of work without any business value. We define a property in a domain object, than map it in a Hibernate file, than create this property even in a DTO, then bind the property of DTO to the view. How many times did we repeat the same code here? Also, an object has state and behavior. Where is the behavior in DTO? If you don’t have behavior, why you need this object on the first place. You can use some data structures like a map for example. If you continue using DTO or you have anemic model, why do you need POJO objects and why do you switch to Hibernate and Spring. You could’ve have the same unnecessary complex and very hard to maintain architecture with EJBs. Anyway, I don’t think that the architecture should be so complex: We have MVC. View - presenting domain objects. If something very, very different should be presented, then you probably have your domain model wrong. At the end, the view should present the domain model of the application. Controller – deals with user/application workflow. (do something- delegate the work to a service-if successful - go to another view – otherwise notify user) Model includes: - Service Layer – very thin layer (deals with application/infrastructure logic – transaction management, security and etc. – example: provide transaction management to dao and delegate the persistence to dao or sends an email notification and so on). - DAO – deals with persistence only. The main purpose is to separate persistence from domain objects. - Domain Model (domain objects) ALL business logic implemented here. Everything that you can think of business logic, including validations, business rules and so on. Since the whole application is built because of (around) the Domain Model, domain objects are presented in every layer (view, service, dao - probably not in the controller though). And YES, building true Domain Driven Architecture with good OOD is very hard an time consuming. Since our nature is to think more in procedural way and since many times we are pressured by deadlines, it is very, very easy to extract business logic all over the application. That’s why probably, we need a clean start like Ruby on Rails :-). Last edited by igorstoyanov; Nov 30th, 2005 at 06:18 PM. |
|
#48
|
|||
|
|||
|
Quote:
And if you take another look at the example, you can see there is a desk involved. What if that desk need to be saved by the deskdao? Who is going to call the save? In your case it would be: Code:
EmployeeService{
void fire(Employee employee){
employee.fire();
employeeDao.save(employee);
deskDao.save(employee.getDesk());
}
}
Quote:
|
|
#49
|
|||
|
|||
|
Using Hibernate aware Domain objects in the web view for over 1.5 years now has thought me that using those kind of domain objects bring very specific problems like the evil LazyInitException!
So responses to that problem where, initialize what you need in the service layer so that the LazyInitExc doesn't occur anymore. I think this kind of solutions is ten time worse then the DRY problem you have when implementing dto's. If I have a large object graph that is passed from my service to the web layer and I need to initialize some collections because of their lazy loading nature, then I have a coupling between my service and web layer!!! Because for an optimized graph were you do not load / init lazy stuff that you will not need in the web layer, you have a coupling, as simple as that! So if you want your large object graph to be used by all kind of views, you will need to fully init / load the object graph ... and that totally rules out the benefits of using hibernate lazy loading (which is in most cases a bless). Alse when developing products with an open api availble for your clients, would you return Hibernate aware domain objects? What if your client suddenly has a lazyInitException. Well ofcoarse we can in that case pre-init all the lazy data. But other problems like hibernate version or last modification data fields shouldn't be visible to the outside world .... so can't we agree that there is a difference between data you work with in and below the service layer and data we work in in the views? Anemic models should disappear from the scene and we should always use smart domain objects for all our logic... But I just get the explaination why we MUST use domain objects in the view, I find there is a fundamentally difference between a domain object and an object that represents a view on a domain model or a serie of domain models, I favor the lack of any kind of business logic that can be accessed through domain objects or whatever in the view, the view is for VIEWING things not for making business descissions... well that ofcoarse my 2 cents ![]() So ok, I know DTO's aren't the holy grail .... god bless for that ... and we need a better approach ... but we have got to admit that using hibernate aware domain objects in the web view isn't the right way to go! It would be great to hear from the Spring guru himself what he thinks about this so ROD IF YOU ARE READING THIS ... ![]() Perhaps we'll never agree on a solution but I guess this thread makes us think about a problem that in this stage of frameworks should already have been cleared out ![]() Grtz |
|
#50
|
|||
|
|||
|
Quote:
What is the best approach under that kind of architecture? My suggestion is to create a pure java facade (with domain objects) based on use case model, one for each actor. And then make another level of facade that fits with jax-rpc constraints (type/constructor constraints that don't belog to the model itself) to export web services using some java2wsdl tool. The objects for this second facade are DTOs for the domain objects of the inner facade, and we need assemblers o helper classes to build those DTOs... Any suggestions to avoid this extra work motivated by the use of web services for rich clients? |
![]() |
| Thread Tools | |
| Display Modes | |
|
|