app architecture, code organization, patterns, and/or exception handling

29 views
Skip to first unread message

t.dave

unread,
Mar 19, 2011, 2:40:38 PM3/19/11
to Grails Startup Support Group
hi all, this has been discussed a few times before on the nabble list
but i wanted to bring it up again here to see what you guys are
doing. i'm wondering how everyone is organizing their code,
specifically in the balance between domain objects, controllers, and
services.

traditionally i haven't been much of a fan of using a rich domain
model and putting anything resembling business logic into the domain.
that said, my history with grails isn't very long so perhaps it's time
i revisited those assumptions. as such, thus far my domain is pretty
simple. and what i've found as my code base has grown is that the
controllers are getting more complicated than i'd like, and i've
pushed more and more logic down into the service layer.

i've been thinking of following this trend through and trying to
simplify my controller layer as much as possible and push all logic
and database access into services or other groovy or java classes. it
seems like once i start getting too much logic into the controller
layer i have a tendency to revert back to almost some sort of
procedural programming mindset which i find annoys me greatly. :)

so, my thought on this would be to have the controllers as thin as
possible, handling navigation and perhaps input sanitizing, and
passing anything of substance (including anything requiring a database
call) to the service layer for processing from there. i'd wrap all
service calls in try/catch blocks, as i occasionally see some
hibernate StaleObjectStateException and other weird errors that are
unanticipated. presumably this approach would make those situations
more palatable. i'd probably need to use DTOs for service calls that
need to pass back multiple objects, but ah well.

so just wondering what others' approaches are. the grails in action
book has about 2 pages (if that) on services, so that's not much
help. are there any sample applications out there that provide a good
architecture example? any patterns you use or would suggest in
organizing grails code?

thanks!

dave


ps. i just looked on amazon and discovered that graeme's "definitive
guide to grails" book has a 2nd edition. thought it still only
covered grails 1.1 or whatever...which the reviews continue to say.
would anyone recommend that or any other books for more guidance on
app architecture?

again, thanks!

Tomas Lin

unread,
Mar 19, 2011, 3:18:06 PM3/19/11
to grails-startup...@googlegroups.com, t.dave
Hiya,

You also want to touch on higher level architectural issues like
breaking things into Plugins, etc. I recommend checking out Peter
Ledbrook's stuff on plugin-oriented architecture -
http://blog.springsource.com/2010/06/01/whats-a-plugin-oriented-architecture/

I think that you will find this distinction between services and
domain objects fairly blurred. In the past, the recommended approach
was to put much of the domain code in Services. But now, with features
like named queries in domain objects, it does make sense to have more
robust domain models.

After a while, the following formula seems to work fairly well for us:

Domain Objects - helper methods related to domain objects and the
children / parents they manage.

Controllers - only use for handling service requests and offloading
the mapping between request parameters and services.

Services - everything else.

We often find that by keeping much of the gorm code that manages
relationships in domain objects, we run either run into fewer cases of
staleObjects or these are more easily tested in isolation. You have a
little more control over catching the merge / lock errors when all
your domain interactions happen inside your domain objects rather than
in services. By moving this up into the service layer, you seem to
leak the database = domain object abstraction.

I.e, we would have methods like Offer.defineBestAllocation() within a
domain object, which will handle cases where new allocations are added
/ removed from an offer. Most of your gorm interactions are kept in
this layer.

Would like to hear more opinions on this.

> --
> You received this message because you are subscribed to the Google Groups "Grails Startup Support Group" group.
> To post to this group, send email to grails-startup...@googlegroups.com.
> To unsubscribe from this group, send email to grails-startup-suppo...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/grails-startup-support-group?hl=en.
>
>

t.dave

unread,
Mar 19, 2011, 5:10:40 PM3/19/11
to Grails Startup Support Group
tomas -

thanks for the input. i'll read peter's blog post but at this point i
only have one application so i think breaking it up into plugins might
be a bit of overkill. my understanding is that once you're running
multiple apps and would like to reuse functionality then that's a good
approach, especially if it's something that's generic enough that you
can contribute back to the community.

what i really need to do at this point is sit down and diagram all the
components and functionality of my app and put on the application
architect hat, as that will definitely facilitate the refactoring. (i
wonder if this has a tendency to fall by the wayside somewhat in an
agile startup environment when everything needs to be done yesterday.
but maybe that's a different topic of discussion.) :)

i'm not familiar with namedQueries either. i'll have to look at that,
and i am interested in the idea of putting all (or the majority, at
least) of the database access into the domain objects. that would
certainly seem to minimize the impact to the rest of the application
if any schema changes or the like were to take place. one practical
question on that though, do you find that approach slows down
development at all? if every time you update the domain the dev env
gets restarted, i can see that might cause something of a productivity
hit. that's probably not something that should dictate the app
architecture, but just wondering if it is a practical concern.

wow i enjoy this kind of discussion. i'd like to hear more opinions
as well!

thanks!

dave


On Mar 19, 2:18 pm, Tomas Lin <tomas...@gmail.com> wrote:
> Hiya,
>
> You also want to touch on higher level architectural issues like
> breaking things into Plugins, etc. I recommend checking out Peter
> Ledbrook's stuff on plugin-oriented architecture -http://blog.springsource.com/2010/06/01/whats-a-plugin-oriented-archi...

Tomas Lin

unread,
Mar 20, 2011, 7:11:31 AM3/20/11
to grails-startup...@googlegroups.com, t.dave
Re: plugins

Conceptually, breaking your application into plugins is probably a
little bit closer to modularizing it into packages.

We found that having many war files gives us a little bit more
flexibility in designing our application. Most projects I worked on
before had a CMS functionality baked right into the main application.
The plugin approach allows us to break it down into different war
packages that might have different deployment cycles while still
reusing the same functionality.

For example, a CRM, CMS and Store module that gets deployed at
different times or on different machines.

It also means that you can protect your entire application from going
down if one of your components goes rouge. We had bad experiences
where a job running awry brings down the entire app. So having a
little bit of isolation does help in this case at the expense of a
more complex deployment procedure.

Re: Code in domains vs. code in services

I think it depends on the complexity of your application. Most sites I
have built are rather dumb when it comes to getting data in and out.
So there have never been many instances where I have seen a difference
in development in services and in domain classes. Smaller, cleaner
methods in domains helps us get away from 'Sprawling Service
Syndrome', which makes it easier to debug and develop.

As the bits of code are fairly atomic in the domain objects, we often
find that it is the same effort to have integration tests that test
out the cross domain functionality ( using test-build-data ) than in
services. I also make extensive use of the grails console, pasting
code out from the domain classes that I think is defective and putting
it back into the domain class once it works. This works better than
reloading or waiting for grails to run integration tests.

I think after working with Grails for a bit, you just get into a
rhythm and understand where to put things when you are trying it out
and developing it, and where to put them when you are done. I also
find that it helped me a lot when I shifted away from the traditional
Java-esque build everything and run it in the app development approach
to using unit / integration tests.

tl;dr - integration test unit test test blargh test domain good.

Dominic Patmore

unread,
Mar 20, 2011, 7:03:35 AM3/20/11
to grails-startup...@googlegroups.com
Hey Dave,
   Thanks for the discussion-I agree, it definitely interesting, and in a way, vital! I'm working on a few POCs, myself over the next couple of months, and one of the things I've very keen on is trying to keep everything as simple as possible and preventing the 'curse of the spaghetti mess' that seems to plague a lot of companies within their codebase. I don't know how well I'll do, but I'm focused on keeping everything small, componentized and tested.

Dom

On Sat, Mar 19, 2011 at 9:10 PM, t.dave <da...@lorgeousdays.com> wrote:

Mike Brocious

unread,
Mar 21, 2011, 10:42:52 AM3/21/11
to grails-startup...@googlegroups.com
+1 for keeping controllers simple.  We treat them as the gateway between the incoming HTTP request and the real business logic.  The purpose of the controller is to transform the HTTP request into something that the service layer can deal with.  And the opposite on the way out....transform the response from the service into the model that will be passed to the GSP to render.

The service layer should not know that it's being invoked in response to a user UI interaction.  We support a REST API in addition to the UI-driven controller layer.  The REST resources act as the gateway in this case, simply transforming the incoming request (parsing the incoming JSON, etc.) and calling the service layer.  So we're able to reuse the business logic in the service layer.

We don't have much of a domain layer at this point because we started with MongoDB as our datastore about a year ago, before GORM supported it.  So we wrote a MongoService that wraps up all the interaction with the Mongo Java driver.  We're starting to look at GORM's Mongo support now, to see if it makes sense to transition.

Mike

t.dave

unread,
Mar 21, 2011, 9:24:16 PM3/21/11
to Grails Startup Support Group
mike -

where do you validate your input data? in the controller layer or the
service layer?


tomas -

re: plugins

been looking into this more, and believe i'm seeing the benefit of the
plugin approach. i'm liking the idea of having different
parts of the application broken out into different pieces with
different deployment schedules. at the moment we have one
server, and i ran into some problem previously with deploying
different versions of the app (test vs. prod) on the same tomcat
instance. i forget the specifics, but it was something to do with
singletons in the grails jars which i had put in the shared /lib
folder. regardless, different issue, but i will certainly keep this
in mind as we (hopefully) grow.

re: tests

first of all, i'm busted. my 10+ years working for two of the biggest
consulting firms in the country did not instill in me the value of
writing tests. (that's what maintenance contracts are for! if it's
buggy they have to pay us more to fix it! <evil laugh>moohoohahaha</
evil laugh>) but this is something i'm going to have to get into my
routine. very fair point about using tests to not have to constantly
restart the server when working with domain objects.

re: domains vs. services

i've sat down and diagrammed my data model relationships and current
use cases. i'm now going to do some GSP/controller/service/domain
swim lane diagrams for some of the use cases to help wrap my mind
around the best approach before diving in and actually refactoring
anything.

i'm seeing some things in my services that could definitely be pushed
down into the domain. but in looking at the use cases, i'm wondering
about creating a new user account and logging in to an existing
account. i started to write up pseudo code on how i'm doing it now
with controllers and services and how i think it might be done in a
more DDD fashion. however, that's getting rather long and i imagine
the process is pretty straightforward. are these kind of activities
still typically done in a service? or as a static method on a domain
class? (i can definitely provide the pseudo code if anyone is
interested or it would help illuminate the decisions to be made.)

on a potentially related note, in your first post above you mentioned:

> I.e, we would have methods like Offer.defineBestAllocation() within a
> domain object, which will handle cases where new allocations are added
> / removed from an offer. Most of your gorm interactions are kept in
> this layer.

in this situation, does that method/closure return an object or update
state in the domain? or both?

thanks everyone for your patience and help as i muddle my way through
this. :)

dave

Mike Brocious

unread,
Mar 21, 2011, 10:35:50 PM3/21/11
to grails-startup...@googlegroups.com
Dave,

We validate in the service layer since that code is run for both of our input pathways (controllers and REST resources).  We can't rely on the controller since we support the RESTful interface that's intended to be used as an API for outside developers to extend our app.  I also like the separation of concerns...validation smells like business logic to me and therefore belongs in the service layer.  Of course, there are performance reasons for doing some client-side validations also (e.g., using JavaScript).

Mike



--

Tomas Lin

unread,
Mar 22, 2011, 6:56:30 AM3/22/11
to grails-startup...@googlegroups.com
DefineBestAllocation would return the best allocation but not set it.

Anything that actually changes values would follow set / get naming
convention. Just keeps it a bit saner.

We tend to use hibernate interceptors for things that have side
effects. So defineBestAllocation can be used externally but also in
the beforeUpdate closure, for example.

I think the line between what is in a service and domain object is a
little blurred. To be clear, we still use a lot of services and keep
more complex interactions in services, but push a lot of our helper
methods into the actual domain classes.

Maybe:

Internal domain class w/ child domain class ----> domain class
Internal domain class association issue ---> domain class
external system w/ external system ---> service
external system w/ internal domain class ---> service
Internal domain class w/ plugin interaction ---> service

Marc Palmer

unread,
Mar 22, 2011, 7:13:14 AM3/22/11
to grails-startup...@googlegroups.com
[repost from correct address duh]

On 19 Mar 2011, at 19:18, Tomas Lin wrote:

> Hiya,
>
> You also want to touch on higher level architectural issues like
> breaking things into Plugins, etc. I recommend checking out Peter
> Ledbrook's stuff on plugin-oriented architecture -

> http://blog.springsource.com/2010/06/01/whats-a-plugin-oriented-architecture/


>
> I think that you will find this distinction between services and
> domain objects fairly blurred. In the past, the recommended approach
> was to put much of the domain code in Services. But now, with features
> like named queries in domain objects, it does make sense to have more
> robust domain models.
>
> After a while, the following formula seems to work fairly well for us:
>
> Domain Objects - helper methods related to domain objects and the
> children / parents they manage.
>
> Controllers - only use for handling service requests and offloading
> the mapping between request parameters and services.
>
> Services - everything else.
>
> We often find that by keeping much of the gorm code that manages
> relationships in domain objects, we run either run into fewer cases of
> staleObjects or these are more easily tested in isolation. You have a
> little more control over catching the merge / lock errors when all
> your domain interactions happen inside your domain objects rather than
> in services. By moving this up into the service layer, you seem to
> leak the database = domain object abstraction.
>

> I.e, we would have methods like Offer.defineBestAllocation() within a
> domain object, which will handle cases where new allocations are added
> / removed from an offer. Most of your gorm interactions are kept in
> this layer.
>

> Would like to hear more opinions on this.
>

Hi Tomas et al,

Yeah I'm very much in the "don't do stuff in the domain classes" camp. I am often alone in this.

It does however depend on the complexity of your model and kind of application.

Whenever I have to inject a service or bean into a domain class I die a little inside. This happens so often later down the line when you realise you do need logic elsewhere that doesn't belong in the domain, it has turned me completely against "smart" domains.

For example in Weceem CMS, there's so much stuff going on behind the scenes relating to caching of metadata relating to nodes, side effects of operations on nodes etc that just cannot be done cleanly using smarts on the domain model.

E.g. before we can save a new content node domain instance, we have a whole bunch of permission checks, events and other stuff to do. Its not even viable for somebody to use the model to create a new instance and save it - it may not even be OK for them to do so.

I don't like the idea of putting stuff in the domain just to avoid other issues with the ORM. If it does help, it feels like something we shouldn't be forced in to :)

Marc
~ ~ ~
Marc Palmer
Freelancer (Grails/Groovy/Java)

Blog > http://www.anyware.co.uk
Resumé > http://www.anyware.co.uk/marc/
Twitter > http://twitter.com/wangjammer5
Grails Rocks > http://www.grailsrocks.com

Reply all
Reply to author
Forward
0 new messages