« It's not a democracy | Main | Definition of insanity »

Aren't classes supposed to have both data and behaviour?

Listen to this articleListen to this article

A bit late off the mark but I only just found an old article on why getters and setters are evil. Combine this with my preference for immutable objects, and JavaBeans often become the devils work. It also fits in nicely with another article I read recently, Martin Fowlers AnemicDomainModel, in that both talk about the value of spending the time to put behaviour back on classes rather than having dumb data objects with essentially procedural functions (in the way I usually see entity and session beans used).

It's a strikingly difficult concept to grasp. I know I struggled with it for years. And I've found it even harder to convince others of since I did get it.

Here's a typical example I see quite often. Now this is only my opinion of course but instead of:

account.setStatus(AccountStatus.CLOSED);

I'd prefer to see this:

account.close();

Internally, the Account might simply look like:

public void close() {
    setStatus(AccountStatus.CLOSED);
}

But it might also do something more. In this trivial example, the benefits are not so obvious but, when the logic becomes more complex, the setStatus() method can become quite large and usually ends up with a switch statement that (hopefully) delegates to separate methods anyway. So why not just call the methods explicitly. After all, the AccountStatus class is really an implementation detail, albeit a common one.

Having said this, deciding where behaviour belongs is often quite difficult. I often find myself using Strategies and Composites instead of inheritence but I've also found this a difficult concept to communicate, with doubters usually exclaiming "But aren't classes supposed to have both data and behaviour?" :-)

Comments

It sounds to me like you should be looking into 'Streamlined Modeling' -- see the 'Website' link below. You'll find it to be very much in line with your current thinking, and with answers to almost all of your questions.
======================================================
In your example of setStatus(closed) vs. close(), Streamlined Modeling specifies that the Account class would have a setStatusClosed() method. That setStatusClosed() method calls a testSetStatusClosed() method that implements the Business Rules associated with whether or not the account can be closed at the moment. After the business rules are checked, the setStatusClosed() method can then call a doSetStatus(closed) method to actually update its internal status. (See http://www.streamlinedmodeling.com/papers/business_rules.pdf under "Enumerated Property Write Accessors" starting on page 5).
======================================================
This is the same as you were saying, with a different naming system and the addition of Business Rule checking. Streamlined Modeling is *very* insistent on encapsulating behavior with data, and provides a set of simple rules for determining which class each bit of behavior goes into.

Nice. I'll check it out. Thanks.

Post a comment