Understanding the Anaemic Domain (responding to Jared - part 1)
The main point to note is that if you check out Martins Bliki, you’ll see that persisting of data is not the kind of rich object behavior that he is describing at all – it is business rules, validations, calculations and the like. He clearly states that putting data persistence code in business objects is orthogonal to his arguments on anaemia.
The truth is that many web application appear to be anaemic because they are primarily CRUD and the domain objects don’t HAVE rich behavior to model. If you don’t have validations, calculated properties or other similar business rules, your domain objects are going to look anaemic because there isn’t any behavior for them to contain!
The one comment I would make is that if you DO have rich getter behaviors (simple example – pull date of birth from db but display the users calculated Age on the screen), it is important to use them consistently on both single records and collections of records, so if you’re using ColdFusion where creation of objects is relatively expensive, you’re going to want to use something like my Iterating Business Object instead of a Gateway returning a recordset to your views for displaying collections of objects. Otherwise you are indeed misusing the service layer (from an OO best practices perspective).
I would argue that for most web apps, the test of a good design would not be how anaemic the business objects were (as that may be an artifact of the simplicity of your application). A better test would be how bloated your service layer is. The service layer can do many things, but it certainly shouldn’t be taking the place of getters and setters with rich behaviors in your domain objects.
All the usual provisos apply. Sometimes an anaemic design is more appropriate for a use case, sometimes OO is a waste of time, and sometimes assembler is the only language worth writing stuff in. This works for most of my universe of use cases. Your mileage may vary.


Glad you noticed... and yeah, I get the reference. ;)
Martin's comments aside, my thoughts on adding persistence layer access to a bean came from the JavaBean spec, which indicates that a bean must be able to save its state in "cold storage" and retrieve it later. Hence, it indicates that persistence, according to the Java spec for beans, needs to be available... again, according to the Sun spec for JavaBeans. It's an interesting conflict that I see arising between ORM and POCFO (that's Plain Old ColdFusion Objects): to make your business objects smart enough to ask a composited "helper" to persist their state or to delegate that to some other entity from outside the model components.
I haven't seen anyone go so far as to put a getBirthdate() call on a Service-layer component... that would (IMO) fairly obviously go on the model component. I would call that "silly", not anemic. Since the term "anemia" comes to us from the medical condition, wherein the number of healthy blood cells is decreased, the parallel to healthy components, ones that have the capabilities they should, is pretty apparent. Having your service layer get an age from a birthdate instead of having a getter return the results of a dateAdd() call is actually rather laughable.
Obviously I have a lot more reading and thinking to do... and I'm sure I'll talk myself in and out of various approaches, but Martin's own Bliki covers TableGateway, RecordGateway, ORM, and DataMapper patterns to solve the problem of persistence in beans. I think it's safe to say there's more than one way to handle this, and, IF you use composition and a persistence delegate of some sort, you're still not adding persistence-layer-specific code to your beans.
Interesting - I hadn't seen the bean spec, so I am a little surprised that it defined persistence as one of the responsibilities of the bean as that definitely isn't a common approach in the Java world.
I should clarify my Age/DoB comment. Lets say you want to display a users age, you're clearly going to call User.getAge() - right? So, given that the vast majority of CF developers seem to use gateways, how do you call User.getAge() when you're cf outputting a recordset containing a collection of users? The only solution is to put the calculation in your view (yuck) or loop through the query in the service layer and create a new column called query.Age based on the query.DoB column (double yuck). My point is that unless you ask a db view to do the work (I'm not a big fan of putting business rules in the db although I get there are some use cases where it makes sense), you're either putting your domain logic (calculating age from DoB) into either your service method or your view. I agree that doing so could be considered laughable, but given that seems to be the default best practice in the CF world, I'm not laughing :->
I personally have a save method in my beans which uses composition to call the associated DAO which uses a DataMapper pattern to map the object into the appropriate inserts into the associated table (remember - your AdminUser may be stored across three normalized tables - so for non trivial ORM mappings there is a bunch of work to do within the data mapper).
For me the Table and Record Gateways don't make much sense. If you have objects where the objects correspond 1:1 to tables in the DB and the properties correspond 1:1 to columns in the table it works. But if your domain model is THAT simple, you probably don't need to be messing with an OO approach to solve your problem anyway.
Looking forward to learning more as you blog about your thinking as you go through this process!
Obviously if we are just dealing with a single property (user.Age) this isn't an issue at all. Now scale up and imagine a Product has a complex set of every changing business rules for displaying the correct Product.getPrice(). There are also complex rules for whether to display a value or not for Product.displayDiscount(). Add in User.getFullName() which concatenates first and last names and maybe 50-60 more custom getters and then you end up putting an awful lot of business logic into your SQL views.
Generally putting the code into SQL provides for better performance, but the tools for managing, commenting and version control tracking on SQL are generally less developed so it is often better to put that into your application. This is where OO really shines - handling lots of these complex business rules and making it easy to maintain them over time.
Didn't mean SQL views - meant rendering logic. Probably talking at cross purposes
My application dispays a users age - model/gateway whatever returns users DOB, no need in my view for getAge(), and rendering logic calculates/displays this as AGE. Client now doesn't like this - wants to display "teeny", "cool guy", or "past it" depending on users age. I'd just redo this in the "view" as in MVC logic. No need to touch any of the business logic DB stuff. Easy to implement alternatives.
As business logic gets more complex OO solves a bunch of those kinds of issues.