What logic should go in the domain class and what should be done in the service in Grails?

I am working on my first Grails application, which includes porting over the old struts web application. There are many existing functions, and when I turn to things, it is very difficult for me to decide what needs to be done in the service, and what should be included directly in the model?

Based on the background of mostly Ruby on Rails development, I feel very inclined to put almost everything into the class of the domain to which it belongs. But, with an application larger than the one I am porting, some classes end in thousands and thousands of lines long.

How do you decide what to do in the domain and what to do in the service? Are there any established best practices? I looked around a bit, but most people seem to recognize this problem.

+7
source share
4 answers

In general, the basic rule that I follow:

If a piece of logic refers to several classes of a domain, put it in the service, otherwise it will be in the domain class.

Without any details about what logic you are dealing with, it’s hard to go much deeper than that, but here are a few more general thoughts:

  • As for presentation representations, they are included in libs tags (or possibly services).
  • For things that deal with figuring out what to send for viewing and with what type to send it, which is included in the controllers (or possibly services)
  • For things that communicate with external objects (i.e., the file system, queues, etc.), they enter services

In general, I tend to make mistakes aside from the fact that I have too many services than something too complicated. In the end, the whole point is what is most important to you, and how you think about the code and how to maintain it.

However, I would like to draw attention to the fact that there is probably a high level of code duplication in what you port. When Grails is built on Groovy and has access to more powerful programming methods like Closures, you can probably clean and simplify most of your code.

+9
source

I personally think that this is not only a decision between the service and the domain class, but also plugins or code.

Think of dynamic Book.findAllByName() like Book.findAllByName() . Great that Grails injects them into domain classes. Otherwise, they would have to be copied to each class of the domain, or they could have been called via the service ( dynamicFinderService.findAllByName('Book') -argh).

So, in my projects, I have quite a few things that I will go to the plugin and implement in the domain classes ...

+1
source

Take a look at the best Grails recommendations.

I think this is a good article explaining good practices.

+1
source

From a Java EE perspective: there is no logic at all in class classes. Keep your domain classes as light and short as possible. Your domain model is the core of your application and should be easily accessible.

  • Grails is designed for dependency injection. All the logic that is in the domain class is difficult to verify, and it is too easy to refactor.
  • You cannot exchange implementations, for example, with services (DI).
  • You cannot easily test your domain class code.
  • You cannot scale your system since your implementations cannot be combined as services.

My recommendation: keep every logic in the services. Services are easy to verify, easy to repeat, easy to maintain, and easy to configure.

Specifically for grails: if you change your domain class, in-memory-DB will be killed, so you will lose test data, which will prevent rapid prototyping.

-one
source

All Articles