Rich Domain Model in Grails
I have been working on grails for quite some time now. As a beginner, I had doubts about where to place the business logic in grails. Seeing the CRUD, one can easily be misled into putting most of the code in the actions, but as the code base goes bigger, it becomes difficult to manage those actions. Coming from the java background, with the previous experience of putting just the getters and setters in the domain classes, it seemed hard for me to visualize business logic in the domain, so I started putting the business logic in the services. It is just natural to use actions as request welcoming and forwarding code blocks. As a result, the actions looked cleaner and easier to follow. The ability of the services to be transactional also simplified the saving of the objects.
But, again as the code base grew, this type of approach also seemed to be unnatural. This approach surely has a tinge of procedural design in it. Devoiding domain objects of the behavior seem to be against the basic idea of object-oriented design. Martin Fowler has rightly called it as ‘Anemic Domain Model‘, depleting the domain classes of their behavior. To give you an example, for searching all the students of a teacher,
teacher.getAllStudents()
seems more natural than
teacherService.getAllStudents(teacher)
The former is more Object Oriented than the latter. Adding the behavior to the domain classes makes them rich, that is why it is called Rich Domain Model. The presence of grails dynamic finders in the domain classes seems to corroborate the model. Not only does the code become easier to understand but also becomes easier for some other developer to locate. Putting the business logic in the domain only is the natural way of Object Oriented Approach.
But now the question comes what are services for in grails context? In my point of view, Services can be used on top of the business logic in the domain. So, they can encapsulate the different tasks in the application. The ability of Services to be transactional also make this approach natural.
Hope this helps.
@Robert, Grails auto recompiles modified sources every 3 seconds by default (and that can be configured). So you don’t ‘have’ to redeploy every time you change the model.
That said, using auto-redeploy in dev and test is a good idea. But I’d be very careful when using it in production. Very few platforms support that well and the ones that do, have it baked right into their core. There are various other mechanisms that allow you to deploy to production with limited or no downtimes. Take a look at Blue-Green Deployments for instance =>
Grails Services are a good candidate to implement Transaction Sctipt
Yes, it’s nice and desirable to create a rich domain model, however there is a major technical problem with this approach in grails: every modification of a domain class automatically causes application restart (which can easily take 1 min for a larger app).
This might easily be the #1 problem with grails. It gives you a very expressive language to write your webapp but at the same time the technical limitations make it impractical to do things right.
Ya Robert, this is one hitch in the model. I usually put the code somewhere else initially. Then when it seems to be working fine I put it into the domain. It saves some restarts for me. One can also use grails console for the purpose.