Wednesday, March 01, 2006

Getters, Setters and Object Orientation

As I read Martin Fowler's Getter Eradicator essay, I wondered for a moment what I was missing. As Fowler says:
[One] sign of trouble [in OO design] is the Data Class - a class that has only fields and accessors. That's almost always a sign of trouble because it's devoid of behavior. If you see one of those you should always be suspicious. Look for who uses the data and try to see if some of this behavior can be moved into the object. In these cases it can be useful to ask yourself 'can I get rid of this getter?' Even if you can't, asking the question may lead to some good movements of behavior.
The problem is my work lately has been full of Data Classes, or what my colleagues and I call Value Objects. A value object is nothing but a bag of properties with getters and setters. A value object is almost devoid of behavior. It is usually passed to or returned by a service that implements the behavior. I found myself wondering, "Is this a bad thing?"

Fowler's essay refers to an even better essay by Allen Holub called Why Getter and Setter Methods Are Evil. Holub warns the reader about violating encapsulation with getters and setters and then back-peddles. There are some valid uses for getters and setters. For example:
The vast majority of OO programs runs on procedural operating systems and talks to procedural databases. The interfaces to these external procedural subsystems are generic by nature. Java Database Connectivity (JDBC) designers don't have a clue about what you'll do with the database, so the class design must be unfocused and highly flexible. Normally, unnecessary flexibility is bad, but in these boundary APIs, the extra flexibility is unavoidable. These boundary-layer classes are loaded with accessor methods simply because the designers have no choice.
That perfectly describes my recent work. I have been working on an abstract, highly flexible Service Provider Interface (SPI). Since I can't force reuse of behavior, I have to define transparent value objects and defer the behavior to each service provider.

All well and good, but Fowler and Holub have reminded me this is not Object Orientation. I guess it is closer to Service Orientation. I am reluctant to call it that only because there is so much other baggage associated with Service Oriented Architecture. In any case, the point is this: Use of getters and setters can be a bad habit. Although I continue to work on my SPI, I occasionally venture up into the Object Oriented layers above my interface. When I do, I'll be on the lookout for inappropriate getters and setters.


Pete said...

I think it's important to seperate the language semantics from the overarching OO concepts. Just because in Java the core structural object is called class doesn't mean we need to apply OO class concepts to every instance of it. In Java a value object, or whatever you want to call it, is just a data bundle, it's not a 'Class' even though it might be implemented via class. If you apply the GSAE rule to Classes and treat VO as just the kin of a hashtable that happens to have a fixed interface, doing the right thing becomes clearer.

Dave Delay said...

You're right, Pete.

The GSAE rule. Did you just make that up? You haven't gotten acronyms out of your system yet, have you? ;-)

Pete said...

Yes I have YCTTBOOIBMBYCTIBMOOTB syndrome - You can take the boy out of IBM but you can't take IBM out of the boy.