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.
I don't think that domain/model classes should be calling services. It ought to be the other way 'round.
A service can orchestrate other services to fulfill a use case. I think that's the right way to go.
I only give my personal opinion. Since grails supports injecting services into domain classes automatically (unlike e.g. injecting services into standard groovy classes, which you have to configure yourself), I'd guess that it was intended to be used that way and therefore is not a bad practice.
Also it makes code more readable with something like "myDomainInstance.someUsefulMethod()", than "someService.someUsefulMethod(myDomainInstance)" (hopefully you know what I mean).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With