Reputation: 1578
This is a design question which confuses me.
As you know, object consist of attributes and behaviours. In web programming, I have implemented several protocol objects as DTO. these are like:
abstract AbstractRequest{
public abstract AbstractResponse apply();
...
}
MathLessonRequest extends AbstractRequest{
public AbstractResponse apply(){
..do something based on request
}
...
}
HistoryLessonRequest extends AbstractRequest{
public AbstractResponse apply(){
..do something based on request
}
}
and what I want to do is , in my controller I simply want to do something like this:
@RestController
class SchoolRequestController{
@RequestMapping(value="/",method = RequestMethod.POST, produces = "application/json")
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public AbstractResponse query(AbstractRequest request){
return request.apply();
}
}
So , as you can see, I want to give Request classes the responsibility to execute all what they are asked for.
My question is , is it a good design? Is it right to give DTO objects the responsibilities to execute what they are for? Or Are DTO objects only for data transfer?
PS:This design comes with a problem that, apply method needs some outer references of some other objects like services, dao etc. So what is the elegant way to inject this dependencies into this instances?
Upvotes: 3
Views: 3631
Reputation: 29867
Usually DTOs have no logic (or very simple transformation logic, such as returning a person's age from a date of birth).
You can use the pattern you have there... definitely, it's just that the objects are not really DTOs but more rich objects (that's usually good). You're not adding a 'DTO' suffix to you class names, so I would say that you're doing fine, because a Request
object could have some behaviour.
I see what you're trying to do. It's possible to do using Dependency Injection + AOP, but I think there are other patterns that might have a more clear distinction and a lot less black magic.
With the approach you want to use, your Request
is the entry point to your application (to the core of your domain) and represents the use case you want to run.
The approach I usually use, which is based on Domain-Driven Design (DDD) and Hexagonal Architecture, is to have DTOs which might some kind of binding to the transport technology (for example xml/json annotations). And I use a layer of Application Services which serve as a façade into the domain logic. The Application Service
is just responsible for orchestration, not for business logic.
As part of the orchestration, the Application Service
needs to get a reference to an object that does have the business logic. In DDD these objects are usually Aggregates.
I think I would write a lot more about this, but there are already quite a few really good resources explaining how to design good applications, and the explanation there is way better than what I can do here :).
If you are interested in this, and don't mind spending a bit more time (and maybe a few bucks). I strongly suggest you to get a copy of Growing Object-Oriented Software and Implementing Domain-Driven Design. Both are excellent books, very easy to read, and luckily all the examples are in Java.
Upvotes: 4