As I’ve been using Grails more and more, I find myself writing code in multiple controllers that really seems like it should be part of a domain class. Sometimes, this domain code contains a call to a service class. For example, I recently wrote a domain method that looked something like this:
class Purchase {
// Injected
def paymentService
String captureTransactionId
Boolean captured
// ...
def capture() {
captureTransactionId = paymentService.capturePurchase( this )
captured = captureTransactionId != null
}
I don’t feel outright dirty writing this code, but I haven’t made a study of best design practices in Grails, so I wanted to get some opinions.
I go back and forth with stuff like this. Before Grails I had no problems with anemic domain classes and putting everything in helpers. The big reason I often ended up with anemic classes is validation. It’s simple to validate nullability, length, etc. inside the class but uniqueness requires a database check and that’s not relevant to a domain class (in a non-Grails app) so I’d move that to a helper. Now I’ve got validation in two places, so I’d consolidate in the helper and would be left with a data-only class.
But Grails replaces the need for DAOs by wiring in GORM methods into domain classes, and also replaces the need for validators by putting validation in the domain classes. So this creates issues when deciding what business logic should go in the domain class and what should be in a service or other helper – services make an excellent place to put business logic that might be needed in a domain class method or validator.
Yes it’s not OO-pure, yes you create a cycle (the service calls the domain class and the domain class calls the service), no it’s not “the Spring way” but a lot of Grails is not “the Spring way”.
Coupling like this does make it harder to separate an app into components or plugins for reuse, but declaring services with ‘def paymentService’ helps a lot since you’re not coupled to a package name or implementation.