One of the definitions of a class is that a class is not just data but also functionality (ie. methods). These methods should contain the logic which describes the behaviour of the instances of the classes (objects). Thus, data and logic are encapsulated. Then you end up with a very logical example eg. a car which has an odometer reading, speedo and state (on/off) and then has methods eg. brake(), accelerate() and lockDoors().
But what if we separated the data from the object? If we define a modern day struct, to group the data for an object, then we simply have a closely-coupled class (ie. service class, manager class) or an aggregate class (which is composed of these structs ie. class Car has many class Wheel) which can perform the business logic where it is needed.
Personally I think this could lead to a purer and cleaner codebase, since there is this logical separation of processes / functions and data. Think about it – the essence of a persistence mechanism is to save the data. You cannot persist a function, at least not in a standardised way.
Many newer languages (and especially functional languages) have a clear distinction between data and functions because they are totally separate concepts. Erlang and Scala are two that come to mind, although Scala lends itself a bit to Java based on the fact it runs on the JVM.
The beauty of this design is that you don’t have to call a bunch of methods (getters and setters, sound familiar?) to serialise an object – you simply serialise the data and you’re done. A perfect mapping. Many hibernate projects i’ve worked on in the past sometimes play with the simple getters and setters and Hibernate cracks it bigtime. If you have conditional logic in these methods which Hibernate doesn’t expect (rightly so) you’ve created a potentially tricky bug to track.
Do we really need to call N getters and setters when constructing an object? Grails allows you to reference class variables directly, whilst under the scene it calls dynamic getters and setters, the reality is that calling them directly wouldn’t have a much different effect.
I’m sure there are many OOP purists which baulk at the idea of having public fields in a class, and the point is valid – you don’t want to expose the internals of your data, only an interface/view/subset of the object. But think of the possibilities having a pure data object gives you – suddenly you can do multiple inheritance via composition without your programming language having to support it (a la Java). Again some languages have mixins and traits which I think are awesome, but use it wisely.
It will be interesting to see where Java goes from here… it has impressed the world with it’s performance, widespread adoption and a fairly robust and precise (though verbose) language. Closures, lemma functions and multiple inheritance are some of the things Java is missing and if it’s not careful, a language like Scala might just overtake it in years to come!