Hey Henry...
I tend to lean more toward the "fat bean, thin service, thin
controller".
I also pass BOs into the views as the API to the data they contain.
I concede that this is far easier when you're dealing with an ORM
framework like Transfer or Reactor. Building your own complex (read:
adequate for use in an application) is not trivial and without a
framework you end up generating or rolling your own for each project.
I'll grant you that sometimes Reactor and Transfer get in the way, but
the regularity with which this happens and the amount of trouble it
causes is minimal.
I don't think having your bean talk to the DB has to mean Active
Record, either... but it can, and it's neither here nor there.
ActiveRecord is a viable approach to solve a problem and the reasons
people hate it are largely philosophical in that they have everything
to do with theory and nothing to do with the reality of the fact that
it just works, and it can be done well. It can also be done poorly,
but what can't?
I think having your beans be smart enough to deal with things like
login/logout state or persisting their own data, be given access to
the service layer, and encapsulate the real weight of the codebase in
question is a good way to actually model the real-world behavior of
the items they represent. I like to use the example of a conference
attendee, who has to register himself, pick up his attendee kit, show
his badge to the security service and ask the hotel desk service for
his room number (at least once). In most ColdFusion applications, the
services would do all that work, bouncing the user around from desk to
desk giving no real help. In the theoretical approach I prefer, the
user himself decides if he knows enough to answer the question or if
he needs to talk to a service to find out the data.
I think almost everyone is right in practice, to one degree or
another, but not everyone is calling things by the right names... OO
is something specific, and passing transfer objects (aka "beans" most
of the time) around between monolithic services isn't it. Having
robust, well-modeled beans that encapsulate behavior based on their
real-world counterparts is really what OO is all about. My problem is
wiht people who build big, procedural code libraries and then call
themselves OO developers. It ain't so. ;)
I agree with Brian here but want to add DRY to the mix... these two
principles will actually, very organically, tell you where to put the
functionality it your application. The idea is that you have one place
in your application that does Activity X (DRY), and if you have an n-
tier application and you step thru (in your head or on paper... UML
activity diagrams FTW!) how the tiers will interact, there's more than
likely a limited set of options as to where the functionality goes, at
least based on TDA. They can be very helpful little slogans.
Tell, Don't Ask
http://www.pragmaticprogrammer.com/articles/tell-dont-ask
Don't Repeat Yourself (aka DRY)
http://en.wikipedia.org/wiki/Don't_repeat_yourself
And with that, I'm off to encapsulate all this into a blog post. :)
This sort of thing is where 99% of my blog posts come from, so I'm
glad I'm involved in lists again! :D
Laterz,
J