Anemic Domain Models
I had actually not heard the term ... or maybe I had and just didn't take any notice... but I just read this article on Ben Nadel's blog about an experience he had in January, working with Hal Helms down in Florida. I was actually rather surprised to see Ben saying that as late as January this year (just 5 months ago) he was still struggling with the philosophy of OO. And moreover, from reading the article, it looks (at least at first blush) like what he's saying is not only that he learned that the way I tend to do things is more in-tune with the fundamental philosophy of OO, but more importantly that as ironic as it may sound this way of thinking about objects that is "more OO-pure" is precisely the kind of thinking that "OO-purists" tend to say they don't like about my solutions (preferring the "anemic domain model" approach).
So okay... let me give an example...
Ben talks about the "Where's George Dollar". Where's George is a website that lets you see all the places one of your bills has been, based on its serial number. This is where the conversation gets really interesting. My tendency with most stuff like this would be to create a Dollar.cfc with methods for getting, setting and generally managing or navigating its history. In my experience at least in the ColdFusion community, most "OO-Purists" don't like that idea because they perceive it as being "too coupled" and would prefer to have a Dollar.cfc bean (like Ben describes) with just getters and setters (and nothing else) for basic, atomic values which is then passed into a DollarHistoryManager.cfc or similar.
Ben's first instinct:
HistoryMan = IOC.getDollarHistoryManager();
qHistory = HistoryMan.getHistory(Dollar);
My first instinct:
qHistory = Dollar.getHistory();
Ben's first instinct is even the way that I perceive is generally encouraged by the 2 ColdFusion frameworks that present themselves as being like more traditional OO development (Mach-II and Model-Glue), where doing anything with the data in an "event" requires the creation of a "listener" or "controller" CFC that has as its sole purpose the job of passing the dollar bean to the other objects that will perform any actual actions with the information.
What is generally cited as the reason not to do things the way I'm naturally inclined to do them (my first instinct) is the notion that it's somehow "more coupled"... which to me just seems odd... it's "more coupled" because it assumes the object will have and connect to a database... Okay, fine... So it works in 98% of cases... why is the 2% edge case a problem, when you can simply subclass the Dollar object to make it fetch its data in some other way for those edge cases?
If anything I perceive what is my first instinct as less coupled because it doesn't require the extra external objects to manipulate the data. Your controller then doesn't have to care at all what objects connect to which services -- all it has to know or care about is that the object has that getHistory() method. Hence the controller is actually less coupled since it only has to worry about the interface to the Dollar and not about the interface to both the Dollar and various service objects that might need or want to use that Dollar.
Hal describes my first instinct as an "idealized model" - creating objects which behave the way we wish real-world objects behaved, rather than the way they actually do behave. In Ben's approach, the Dollar behaves the way a real-world dollar behaves - the only info you can get from it is what is printed directly on it. If you want to know where it's been, you have to go to an external resources like the Where's George site and enter its data to get your history. And the objects in Ben's design would be the same way -- the only thing you can get from the Dollar object would be its atomic data (values that can be printed on its surface), requiring the system to find some external resource if it wants any other information about that Dollar. In my approach, what Hal describes as an "idealized model", the "idealized Dollar" doesn't force you to go find some external resource. It's like having a magical bill that talks and saying "hey you, where have you been" and having the bill itself rattle off a list of places.
It's where the Dollar meets the cell phone. Years ago if you wanted to make a call, you had to go find a phone. Now you just carry a phone with you. But if you want to know the history of a bill, you're still stuck going and finding a computer with internet access, even though you carry bills all the time. So in an ideal world, since we already carry bills, it would be great for "smart money" to be able to give us that information while we're standing on the corner. This is perhaps a bad example simply because getting the history of a bill, while interesting, usually isn't very useful (if at all).
Ben makes one last comment that the Anemic Domain model generally gives you all the overhead of OO without the benefits. It's interesting if not downright frustrating to me because at least I personally perceive that a preference for anemic domain models as being "the way things are done in OO" or "the way things are done in Java" is one of the larger reasons why more people haven't either tried or used the onTap framework.
Am I way off-base? What do you think?

There are no comments for this entry.
[Add Comment]