开发者

Is it bad design to call Grails services from domain objects? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.

Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.

Closed 4 years ago.

Improve this question

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 = ca开发者_开发问答ptureTransactionId != 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).


I'm not sure whether it's right or wrong.

In cases like the example, what about going one way or the other: either putting the paymentService.capturePurchase() code inside the Purchase class, or you could putting all the logic in the service?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜