Tuesday, June 17, 2008

What No Getters?

I was intrigued reading an article by Michael Feathers recently. Although the main topic of conversation was flawed thinking in the TDD world, I was struck by the point about writing OO code with no getters. This sounded like an interesting idea to me, as I have long since thought that setters and getters are very much an OO anti-pattern, exposing the details of an object unnecessarily much of the time. 

Many blogs are covering the subject right now, and I am still reading through them and trying to remain open minded. Here are a few examples -

http://peripateticaxiom.blogspot.com/2008/06/tdd-mocks-and-design.html
http://moffdub.wordpress.com/2008/06/16/the-getter-setter-debate/

Martin Fowler has a slightly different perspective -

http://martinfowler.com/bliki/GetterEradicator.html

4 comments:

MoffDub said...

Hey, thanks for the link. You're right, this is a pretty hot topic right now, despite uncovering an article about it from four years ago:

http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html

Here are a few other articles for you:

http://typicalprogrammer.com/?p=23
http://dotnet.robertmao.com/2008/06/17/write-code-with-no-getters/

When you read through the material, remember something I forgot: no getters is just as bad as getters for everything. Some articles can give the impression that they're saying no getters is the way to go always.

Andrew said...

Moffdub, thanks for the articles. After reading some of them and the responses, I must say I am beginning to get confused myself. So my opinion is turning more toward Martin Fowler's.

I agree that getters and setters are massively abused and overused, but I have no doubt that there are perfectly valid occasions on which to use them.

Certainly, their use can be drastically limited. In a number of comments people have advocated the use of format statements in business objects to permit the UI layer to ask the object for a formatted string. This is no better than using getters in my opinion, because the object is now no longer doing only one thing and screen representation logic doesn't belong in the business domain.

There's a general layering principle that says that it ok for classes in a layer to depend on the ones below it, but not vice versa. In past projects, I have used UI layer formatting classes, which have the sole responsibility to accept an object and produce a string representation relevant for a graphical rendering for specific user interface needs. These may have broken the getter rule, but the use of the getter can be greatly restricted.

I see the problem as more of an educational issue. People are simply not taught OOP. Sure I picked up all the definitions in college, but IMHO it really takes an apprenticeship with someone who has an understanding to truly 'get it'.

As an example - I saw some comments with code as follows -

Number getPrice() {
...
}

To me, a price implies that there might be some price specific behavior, so why return a Number - what's wrong with returning a Price object? Equally, there are many references to returning names as Strings, I would use a Name object. Just because something seems small, there is often behavior associated with it, and if nothing else, it can also simplify debugging in statically typed languages.

Enjoying your blog BTW - keep up the good work!

MoffDub said...

Every rule has exceptions. One key exception to this rule is it doesn't apply, like you said, at layer boundaries.

I began to "get" (no pun intended) the essence of the no-getters argument recently when writing code like this:

return this.getA().getB().Contains("something");

It didn't look right to me because, ironically, of a different code smell... too many middle men or something of the like. I refactored to:

return this.A.BContains("something");

which tackles two code smells at once.

And I'll agree that part of the problem is education. Most people don't see Smalltalk code at all in college. I certainly didn't, and only heard it alluded to by some professors. All I needed to do was read a tutorial on it to get the point of sending messages to objects whenever possible. You very rarely see getters in Smalltalk, which is so-called "true OO".

MoffDub said...

I have written a new post on my blog detailing a pattern-based solution to this problem here.