Search code examples
javaspringspring-mvcpolymorphismdto

Doubts spring mvc


I'm developing a Spring Boot MVC application and, after reading many guides and comments, I still have some doubts that I have not unmarked.

1: I do not want an anemic pattern, so I do not have a monolithic service where all the services are called each other, but these communicate only with repository instantiating entity, inside which I put the business logic, correct?

2: where to put the conversion functions entitiy-> dto? I read that someone puts them in the Controller, others in the Service, others on the same domain .. at the moment the cleanest solution and I prefer to have a Builder of the DTO that lends the entity input, okay I have contraindications?

3: polymorphism and inheritance: I have a service that composes some menu levels according to an attribute of the entity in question. I do not want to have blocks of if anywhere, I wanted to be able to put this logic in a single point, to instantiate the correct class (which I do not know a priori) and to exploit the polymorphism, how can I do? considered to involve service, entity and related logic ..

thank you so much


Solution

  • Your questions are more related to software design in general rather than specific to the Spring framework. Allowing the framework to dictate how to organize your code, has some downsides.

    But to answer your questions:

    1. Depending on how complex and interrelated your model is, there are different options, for the cases where there is not big interdependence between the entities in the model, the 3 layer approach is simple and good enough, but if your model is more complex, you could take a look into the concept of Aggregates, and keep the invariants hidden inside.
    2. Constructing the DTO with the Entity as parameter is a good solution, whenever changes needs to be made to either the DTO or the Entity, the amount of code to maintain is not as much as with other approaches, it is not just about the conversion code, it is also about methods signatures, and all of the usages. This approach also follows the Dependency Inversion principle which states that low level modules (presentation in this case) should depend on high level policies (business logic) and not the other way around. But it is not the only valid solution, it always depends on your concrete case.
    3. If you want to return an object from your service that can be an instance of different types, there are different ways to do so, a way to do so (but not the only one, and again, the best way always depends on your concrete case):

      • For the type control, one option would be to make the method return type an interface, and then have the possible different objects that can be returned to extend that interface.
      • For the construction of the different objects, you can encapsulate it inside of the service in a private function if that is the only place you are going to use it, or if you are going to use it in more places, then you could extract it to a factory and use it as a colaborator of the service. For the construction you won't be able to avoid the if checks, but outside the service, once you serve the different instances, then you won't need to do more if checks.
      • and finally in the service return the instance that you constructed, as it implements the interface, the compiler will still be happy about it.

    Hope it helps!