Should we use the same business classes on the server and client?

Imagine that you have a business domain model on a server application, and you are going to develop a rich client application.

You can use DTO to transfer data to the client, change on the server, or use WCF services and create new classes on the client.

Another way is to transfer the same objects as on the server at the level of business logic. It can also be classes used by ORM. In this case, the classes should not contain north-specific logic, but they may contain some general logic.

My questions:

  • Which option do you use and which do you recommend to use in new projects?
  • What's better?
  • Is the second one better in some cases and how can you describe these cases?
  • How many applications use the first / second approach?
  • How to choose a specific application?
+4
source share
3 answers

It was simply not easy for us to find the answer to this question in our project. This is history:

We thought that reusing classes is great and will reduce many repetitive things. NHibernate allows you to detach and reattach classes to sessions, so this seemed trivial.

  • The first and biggest problem that we encountered was that you cannot send the entire database, so we had to split the entity model into parts and link them using pointers instead of regular links. This made the queries very complicated.

  • We had to implement some tricks, because they had problems with serialization, persistence and data binding. These rather ugly hacks went to the same classes. They became more and more.

  • Attributes seem harmless until you see a large list of attributes for each class and each property, because each layer adds its attributes.

  • Objects implicitly began to support two "modes": DTO mode and constant mode. This became apparent when methods such as PrepareSerialization or AfterDatabaseRetrieval and others like that appeared. Some properties can only be used on the server, others only on the client.

Obviously, service has become a nightmare. No one dared to change the object anymore, because you had to change things throughout the system.

Then we started switching to Dtos.

After a huge amount of work, we were able to rewrite some important parts of the system for using Dtos. And - suddenly everyone became happy.

You can support serialization. You can maintain a database model and optimize queries. You can make changes to the cient model without breaking anything.

Conclusion: The effort to maintain such classes for each level is ridiculous compared to the loss of maintainability when the same classes are used in all layers.

There are also some trivial entities and value type types that are simultaneously used as entities and Dtos.

I could imagine that a small application consisting only of trivial objects could live without Dtos.

+4
source

You should write the smallest classes that fit your requirements. That way, you are less likely to repeat yourself, there are fewer tests, and there are fewer things that can go wrong when you need to change your code.

If your client code really needs to follow the domain logic , you must either:

1) deserialize directly into domain model classes (especially if you use an ORM that supports ignorance of ignorance).

 // Customer is a business object / aggregate root with domain logic ICustomer customer = customerRepository.Get<Customer>(customerId); 

2) Use data transfer objects to initialize domain model classes:

 // Given a customer data transfer object ICustomer customer = new Customer(customerDto); 

I would rather not write DTO if I don't need it, so I prefer the first approach. But sometimes DTOs are necessary, for example, when you consume auto-generated classes created by service proxies, or if you are a service that exposes your own DTOs.

If a client should not follow business logic , it should never know about your domain model classes. In these cases, the client must use data transfer objects or user-defined view model classes.

+2
source

I have to agree with the two previous answers. However, keep in mind the effort to keep the BO / DTO classes in sync (I would consider using code generation).

See my answer here for those who wanted to go the other direction - they wanted to consolidate a lot of DTO / BOs in their system.

0
source

All Articles