I finally came to it: I hate Data Transfer Objects.
I can't explain why a lot of people still stick with this unconfortable pattern and most of them continue to ignore the cons of this choice. Now I'll try to explain my opinion by listing why I think this should be enlisted as anti-pattern.
- whenever you have to return or receive an object you must always copy it using almost double heap memory than normal (yeah, I know it's not really double, but it is something near it)
- if you should return or receive a complex structure you have two choices: deep copy the structure or use multiple interactions, in both cases you are loosing heap space and processing time
- almost any change to the business model interfaces will be reflected on the transfer objects AND on the code which maps the two (the latter does not apply in case you use introspection which is slower and lesser customizable) more than doubling the maintenance time and is error prone
- programmers tend to confuse the difference between model objects and DTOs adding utility methods to the former and business logic to the latter
- if in certain situations you need additional info on the client side from a returned DTO you have two choices: embed a service call into the DTO (which hides the complexity but expose to a performance hit as your users don't know they are starting another interaction) or call another service to obtain the additional infos (which adds complexity to your service interface)
- if you need to return or receive almost all the informations stored in your business model object just do it, return or receive your business model object
- whenever you need to return a DTO, may be to reduce the informations providen by hiding some properties/methods, return an interface which your business model object will implement
- whenever you need to receive a DTO you have two choices: use a business model object ancestor or use a business model object component; the choice depends on your business model design, if you are used to build by composition or inheritance
- when you need to return a complex structure just initialize the structure before returning it (this is needed to avoid lazy initialization errors)
Four simple rules to avoid class and memory duplication with a lot of processing time spent copying datas from one object to another.
Do you see situations where this solution is not applicable? Let me know, I'm sure I can find a non DTO based solution.