Data Transfer Objects or Smart Objects?
One major aspect that I always end up thinking about when I consider the custom classes approach is whether it's okay to send a subset of the domain model to rich clientsthat is, sending smart objects with business rules. Another approach is to send data transfer objects (DTO), which are filled by copying data from the domain model at the application server. Then the DTOs are sent over the wire.
There are problems with both approaches (as always, of course). If we send domain model objects to the client, the client is tightly coupled to the domain model. On the other hand, we don't add to the overhead by having to copy data between objects, and we also lessen the development overhead by having less code to write and maintain. Furthermore, we don't lose the advantage of having business rules checked at the client, so the application server receives fewer unsaveable objects.
Another problem with letting the client talk directly to the domain model is, of course, that the client must use the correct version of the domain model, so the correct rules are checked. .NET has a lot of functionality for dealing with versioning, such as automatic download. It's also the case that even if wrong business rules are checked at the client, even if there is not a version conflict detected, you should check at the server side as well so that you don't accept any incorrect data. Most often, you shouldn't trust the client because you don't know what has been done to your data.
Of course, this doesn't solve the problem that an incorrect version of the domain model at the client might be too restrictive . . . .
Whether to use DTOs is actually a huge topic on its own. I just wanted to briefly touch upon it here. Anyway, no matter how important this design decision is, it doesn't actually affect our discussion of today because I'm mostly discussing data (not behavior) in this article. Even if you prefer not to send smart objects to your rich clients, the performance implications are important for your data transfer objects.
Early on in this article, I said that data containers are about updating data also. I want to strongly emphasize that the approach of using custom classes is actually even more positive when it comes to writing because the objects that travel are smart and know about the business rules to check.