This post originated from an RSS feed registered with Java Buzz
by dion.
Original Post: Model talking to Service Layer: Good practice or bad?
Feed Title: techno.blog(Dion)
Feed URL: http://feeds.feedburner.com/dion
Feed Description: blogging about life the universe and everything tech
In general I am a fan of OO practices, and giving as much behaviour as possible to my object model. Of course, this is within reason, and I only want my model to have the logic that makes sense for the given objects.
However, I often find that a lot changes when I see model's that are used on the web tier.
I often run across this pattern:
Action talks to Service layer which returns dumb model objects
Model objects are placed in the request
View generates page, using the model
Since the model contains simple properties, with the odd piece of simple logic, and relationships, if a page (view) needs to get more information, it either:
Runs another action, which in turn talks to the service layer again to get the new info
The original action has multiple calls to the service layer
I actually prefer a different way of doing things. I want the dumb model smarter. I want to do real object design, and have rich behaviour in the model. In fact, I sometimes take it so far that my userSession object can traverse to most pieces of data as needed, but that is another matter.
What does this all mean? Imagine that I have a core model object that I return, and I want the object to have a method: Collection getAssociatedActivities().
What does this method do? Well, it could simply be walking our in-memory data, doing a lot of munging and calculations to work out the association based on rules.
However, this may not be enough. Maybe a complicated query needs to be done to work this out. Rather than using a Comparator and sorting through the model, and doing a bunch of aggregations, I want to let the database do what a database is good at.
This means that the implementation of this method changes from:
public Collection getAssociatedActivities() {
// sort through data model, using a lot of Comparators, making sure the data is all loaded, etc etc.
// 50 lines later...
return theAssociatedActivities;
}
to something like:
public Collection getAssociatedActivities() {
SomeService service = getSomeService(); // injected, via a BeanLookup, or what have you
return service.calculateAssociatedActivities(); // in here the services tier talks to the data tier to do a lot of the work
}
Implementation Encapsulation for Performance
What I like about tweaking the implementation of this method, is the fact that it is all encapsulated. At first I can put it in code directly. If it needs to go back to the service tier based on:
Performance: Turns out the DB can do this a lot faster
Cleanliness: Nicer to be shared at that tier
it can simply be done.
Choosing in the web tier
Compare this to an approach I see all the time, in which the web tier decides what value objects it wants back. In this case, when the interface needs to change to hit the services tier, either:
The main Action hits the services tier again to grab the associated activies object and plugs it in the request
The view does a pull which hits another Action, responsible to hitting the services tier and getting the associated objects
Any which way, you end up changing a lot, just for this issue. The web tier is totally changed for performance reasons. The rich object model is compromised, taking functionality out, for performance reasons.
Conclusion
I like rich models, and I like hidding as much as possible underneath. This allows me to change the engine under the hood without bugging the folks on the web tier. Thoughts?