I am writing a web service. I am also writing a web client which uses开发者_运维百科 this web service. I've experienced some of the pain of trying to send domain objects over the wire (cyclic references, lazy loading, etc. -- see e.g. Davy Brion's post on why it's a bad idea). So, I am going to use DTOs to transfer between these two tiers.
Being in charge of both ends, I am able to control the design of the DTOs. Now I'm wondering, what drives the design of the DTO? Is it the user interface on the client-side? Do I create DTOs based on what views/screens the client will have? Or it something service-side that should dictate the contract of the DTOs I send out, and the client has to work with what it's given?
I think in many cases the DTO model is not that important as the domain model, so I'm very pragmatic in this issue. We are writing DTO very close to what the client actually needs, because it is the only consumer. (There are processes calling the server, they are using different DTO's.) There could even be different DTO's for different views to the data. That's the power of the DTO's.
To be clear: it should be driven by what the client needs, not client-specific. For instance, use general data types, not view-specific data types. Not every change (eg. UI design change) on a view should result in a change of DTO's. This is a general rule of maintainability, nothing special.
Designing your DTOs can be a hard task especially because there are many concerns coming into play. Usually performance considerations can prevent you from completely abstracting from the UI. Let's say you have multiple UI representations for the same object, e.g. a tree, grid and a detail pane. Each of them will need a different subset of properties, based on what you actually display. You can design a common DTO to contain a union of all those properties, but it might be expensive to construct such a DTO, load the data from the store and transfer it over the wire. You might end up transferring a rich object graph with lots of data just to display the name of the object in the UI.
On the other hand, if you go for a DTO per UI context, you'll quickly end up with a class explosion problem having hundreds of DTO representing nearly the same object, with a slightly modified subset of properties. Reuse of code and readability will suffer and it might become unmanageable in the long run.
As there is no silver bullet, it requires a sensitive approach where you find the compromise between the performance and other aspects, maybe using up to 3 different DTO types per Domain object and reusing them in different contexts.
hejdig.
When I am not sure about an interface I usually write the caller first because then I have the context of the use of the method. It makes me give the method a name that is understood and parameters that are fitted to the user of the method.
/OF
Now I'm wondering, what drives the design of the DTO?
Personally I think the data should dictate the design of the DTO, it should be driven purely by the purpose of the DTO, which is serialization. To that end, I'd make it a completely flat data structure with simple get/set properties. The last thing you want to do is compromise the integrity of the DTOs (simple) purpose by letting presentation layer issues come into play.
精彩评论