There was a post on the Grails Mailing list today asking about the philosophy of Grails. This is my response:
I think I might have ripped this off from somewhere, but fundamentally there are 4 questions to answer for a basic application like this:
- How do you display data to a User?
- How do you implement business logic?
- How do you encapsulate complex business logic (Domain) interactions?
- How do you implement data access?
Most of the time when there is a layered approach one of 2 things happen. You've implemented a Transaction Script pattern where your business logic is implemented in the Service layer, or your Services are thin wrappers around a Data Access layer. Transaction Script is fine, but doesn't handle complexity as well as a more Domain Driven, OO approach. The thin-wrapper thing is mostly just busy work and annoying to me.
- Controllers gather Data and hand it to GSPs for rendering
- Business Logic goes in Domain Objects
- Data Access goes in Domain Objects
- Complex Interaction are encapsulated in Services
Thin ControllersKeep your controllers thin so they just mediate between views and Domains.
Active Record2&3 happen in the same Domain objects because Grails implements the Active Record pattern. So, implement any extra queries in the Domain objects themselves.
Services for EncapsulationOnly introduce a Service when you have complex interactions (multiple objects being constructed or working together to answer a question) among multiple Domain objects that need to be encapsulated.
This is a Domain Driven framework. The complexity should be encapsulated in your Domain Objects so you can use Polymorphism to manage complexity.