It seems to me there has been a trend recently to remove behavior from model classes and to remove state from service classes. This has resulted in a kind of a “Separation of Search and State.”
There are good reasons why our model classes are getting stripped of their behaviour and becoming DOJOs, “Dumb Old Java Objects” (also called DTOs, “Data Transfer Objects.”) Modern persistence tools make persistence behavior practically transparent to the coder. And modern remoting tools make remote method calls super-easy. These are wonderful technologies, and are becoming increasingly necessary on projects where low-cost interoperability and connectivity are assumed.
But I think those tools are the reason why we have abandoned cherished object-oriented principles of yore such as encapsulation, polymorphism, and the old chestnut that the objects are the nouns and the methods are the verbs. These days, you just don’t want behaviour on objects that will be passing through communication and persistence layers. Just the state please.
RANT ALERT: I need to digress for a minute here. One thing that bugs me about these model classes is all the getters and setters. I mean, if all your class contains is a list of private fields and getters and setters for them, then please, for the love of code coverage, drop the getters and setters. If you have a field on a class, and anyone can “get” and “set” the value of that field, then that field is “public”. Seriously! Okay, now back to the point I was trying to make…
So classes that hold state and have no behaviour aren’t particularly Object Oriented. In the same way, classes that have behaviour but no state are also not particularly Object Oriented.
The rise of Service Oriented Architecture, Loose Coupling and their enabler Spring have also contributed to this second phenomenon. Inversion of control is awesome goodness. Joshua Bloch suggested that if you ever write a method that has more than two parameters you’re probably doing something wrong. Injecting the other parameters you need as services just makes it so much easier to keep method parameter lists small. But as soon as you’re injecting a service, then chances are, you’re only going to want one instance of that service floating around inside your lightweight container, and that means you probably don’t want that service object to have any state. But that’s just one reason why you don’t want services to have state. Another is to make it easy to turn it into a Web Service, or to not have to worry about concurrency, or so that it’s just plain simple to use. Any state a service needs to do its job should be passed in as a parameter. Just the behaviour please.
It almost feels like we’re getting back to what programming was like in the 70s and 80s, when we ran “jobs” against “data records”, you know, mainframe stuff.
I think the fact that we have been moving towards this strict separation of state and behaviour is a natural consequence of us following best coding practices. It is the direction we should be going. What I feel needs to happen. though, is some reflection on how this trend should get us to question some of our more sacred coding practices; Practices that made sense back in the day when we actually did Object Oriented programming, but that may actually no longer make sense in this new world of Dumb Old Java Objects and Services that operate on them.