If this is Object Calisthenics, I think I'll stay on the couch

May 6, 2008 ⋅ programming ⋅ 20 Comments »

Via Raganwald, I saw this post by Andrew Birnstock: Perfecting OO’s Small Classes and Short Methods. The post is a summary of an essay by Jeff Bay called Object Calisthenics, from the new Pragmatic Programmers book The ThoughtWorks Anthology.

“Object Calisthenics” is supposedly an exercise to get you to write better object-oriented code. Reading through the suggestions, I couldn’t decide if the article was serious or not. From Andrew’s summary:

  1. Use only one level of indentation per method. If you need more than one level, you need to create a second method and call it from the first. This is one of the most important constraints in the exercise.

  2. Don’t use the ‘else’ keyword. Test for a condition with an if-statement and exit the routine if it’s not met. This prevents if-else chaining; and every routine does just one thing. You’re getting the idea.

  3. Wrap all primitives and strings. This directly addresses “primitive obsession.” If you want to use an integer, you first have to create a class (even an inner class) to identify it’s true role. So zip codes are an object not an integer, for example. This makes for far clearer and more testable code.

From what I can tell, this really is serious. These are supposed to be the object-oriented equivalent of chin-ups, designed to whip you into shape to write better OO code.

This strikes me as so bogus, I can’t even begin to describe it.

I’m not against OO: I’m a huge fan of Smalltalk, and I cut my programming teeth at one of the oldest object-oriented development shops. In fact, I keep thinking of something that Steve Northover used to say to me when I was on my first work term at OTI:

“That which obscures my code is bad.”

If you’ve ever seen a large body of code that adheres to The One True OO StyleTM — like say, Smalltalk class libraries — you’ll understand that almost every step you take towards “true OO” is just another way of obscuring the meaning of your code. If you break your code up into 10 different methods, then that’s 10 different places I have to look to figure out what is going on. You’re just writing spaghetti code by a different name. If you’re building a very large library, then maybe, just maybe, the additional flexibility is worth it.

I think Paul Graham sums it up best in his essay Why Arc Isn’t Especially Object-Oriented:

My own feeling is that object-oriented programming is a useful technique in some cases, but it isn’t something that has to pervade every program you write. You should be able to define new types, but you shouldn’t have to express every program as the definition of new types.


20 Comments:

  1. Hugh S. Myers - May 6, 2008:

    Now, now--- don't pick on poor little zippy! He is more useful as an object; there's the +4 part and the ability to identify the 'where' and so on. You could add UPS rates, FED EX delivery times and so on. That said, you are absolutely correct about the quoted gibberish. This is worse the the go4's extreme misunderstanding of 'A Pattern Language'! Paul's generalization is correct, objects for objects sake is bad; just enough to do the job, not one class more.

    --hsm

  2. mark - May 6, 2008:

    But this may be in the smalltalk world of view, I want you to point out to the ruby world because it is a lot more practical than the smalltalk way to split everything up into thousand files, and then need a VM to survive this chaos :)

  3. Mike Kramlich - May 7, 2008:

    Good post. I think OO is a great technique for solving certain kinds of problems, and a good way of increasing extensibility. It can also be abused and misapplied. I've come to call this phenomenon TOO or "Too Object Oriented". Whenever you see an application that's broken down into hundreds of classes, hundreds of methods, and once you slurp it all into your mind and finally understand what the heck it's doing you realize it could have been made much simpler with an OO design. This anti-pattern often occurs in tandem with the "Look ma, I bought the Design Patterns book! Me iz smart now!" pattern, where an application has tons of Capital Letter Design Pattern classes, but again, is way more complex than is needed.

    I tend to start with a C/procedural approach, then only add classes where I think the benefit outweighs the costs. A low-formalism and low-keystroke language like Python allows that to happen more often than not, in my experience. Java is more likely to make you go TOO too soon. In fact I'd have to say that all the bloated, over-engineered software I've seen has been Java or C++, usually Java. Java usually compounds the bloat by using lots of XML to do the high-level wiring of all the classes (via Spring, for example.) I've never seen a Python or C app bloated in this manner.

  4. Mike Kramlich - May 7, 2008:

    I meant to say, " ... you realize it could have been made much simpler WITHOUT an OO design."

  5. Mogens Heller Grabe - May 7, 2008:

    When I read Binstock's post, "Perfecting OO’s Small Classes and Short Methods," I thought that it would be an interesting exercise to try to adhere to the rules specified. BUT I think is it an important point that it is merely an exercise in OO, not a way of practicing OO.

    Nobody thinks push-ups are bad because it's a stupid way of lifting heavy stuff ... :-)

  6. Jake Voytko - May 7, 2008:

    I understand your objection, and it is a valid one. It would be silly and hyper-restrictive for a developer to actually undertake object oriented programming through these means.

    However, you are taking the exercise much more seriously than is intended. While the author notes that people have written real projects with these constraints, the constraints look like they are intentionally restrictive and artificial, intended for those who are already writing bad code and just don't get it.

    This is the case with most good programming exercises.

    This is no different than having a functional programming exercise that requires that you never ever declare a variable, and never have a function that takes more than one parameter. You might be a fool to implement a production system in this manner, but the functional constraints forces the newbie to think in a new way.

    The goal is not for the newbie to 100% adopt a style, it's for the few "aha!" and "oh!" moments. It looks like this exercise is defined in much the same manner. Were you to actually complete the exercise, it would let you completely evaluate the claims of the article. Is it more testable? Is it more readable? Did I write it faster?

    I myself am currently in a fight to the death against finals, but I'm going to give the exercise a chance on some code I wrote a year ago and see if I get any "aha!" moments.

  7. Finding Value in Bogosity - Push cx - May 7, 2008:

    [...] Then I saw a blog post saying: This strikes me as so bogus, I can’t even begin to describe it. [...]

  8. Patrick - May 7, 2008:

    @hsm: You're right, I can imagine where having a zip code object would be useful.

  9. Patrick - May 7, 2008:

    @mark: Do you mean that Ruby is more practical? Because you can put multiple classes one file, unlike in Smalltalk where every class is a new item in the class browser?

  10. Patrick - May 7, 2008:

    @Mike Kramlich: I totally agree. That's the same approach I like to take too. I think a lot of the Python standard libraries are good examples of the right amount of OO.

  11. Patrick - May 7, 2008:

    @Mogens Heller Grabe: Right, but if it's an exercise, then you need to make sure that it's working the right muscles, and not hurting your overall form. My belief is that these exercises are not working the right muscles.

  12. Patrick - May 7, 2008:

    @Jake Voytko: I'm interested to hear what you think after doing the exercise.

  13. Mogens Heller Grabe - May 7, 2008:

    @Patrick: Yeah, I see.

    But I think for some people this kind of exercise might prove to be sort of an eye-opener or something. Sometimes you need to come up with restrictions or rules to break out of your (bad) habits.

  14. Raoul Duke - May 7, 2008:

    Not that you or anybody asked me, but I think those 3 points of the exercise are very good food for thought (and they've been much on my mind recently even before I came across all this). Think "types" and "functions" instead of "objects" and "methods", if that helps any; I think the ideas are just as valid there.

    Of course, everything can be taken to an extreme, so one has to know where and how to dial it in. E.g. I would guess in Java that putting the units (e.g. mph) into your types would suck pretty quickly, whereas putting them into the variable names wouldn't be so bad and would help address the underlying concerns. I think that is an indictment of Java rather than a great thing, tho, that you can't do lots of types conveniently.

  15. Waterbreath - May 13, 2008:

    You’re just writing spaghetti code by a different name

    We call it "ravioli code" where I'm from... Code pasta with a proliferation of object pockets instead of procedural noodles.

  16. Patrick - May 13, 2008:

    @Waterbreath: Ha, I'd never heard that one before! Found a writeup on THE wiki: http://c2.com/cgi/wiki?RavioliCode

  17. Joel Neely - May 17, 2008:

    I have a longstanding meta-observation that any reaction of the form "At first glance, this is obviously bogus" is itself, at first glance, obviously bogus. (Including the one I just stated. ;-)

    Although passive voice sometimes communicates effectively, I have learned to improve my writing by deliberately asking myself, "How could I rewrite that paragraph without using any passive verbs?" Similarly, after reading a bit of General Semantics, I found it very instructive to try to write and speak without using any form of the word "is". Both exercises were worthwhile, even if I don't do all of my writing under those conditions.

    Some people reacted to Dijkstra's criticism of the "goto" statement by rejecting it as unreasonable or impossible. Some reacted by proposing brute-force goto-ectomy practices that (further) obscured the structure of the code. But some took it as a challenge to rethink program design practices. Few languages today offer "goto" at all, much less as a primary composition mechanism.

    Although I've been doing software for about 40 years now, I found it useful to reconsider some code I'd recently written in view of the constraints of the exercise under discussion. In one case, by forcing myself to remove one layer of conditional nesting, I recognized a hidden symmetry that I had not consciously noticed before.

    Maybe some of us are so good as programmers that there's no room for improvement or re-thinking. I make no such claim for myself. Instead, I found the exercise instructive.

  18. Working Through the “OO’s Small Classes and Short Methods” Exercise : So Jake Says: - May 26, 2008:

    [...] These constraints are tough when you try to adhere to all of them at once. They have also received their fair share of criticism and teasing from the mainstream blogging community. [...]

  19. owen - June 3, 2008:

    From what I've seen it comes down to alot of "what if" programming. Trying to teach someone a "fix all" solution without giving proper examples and use-cases will only make you look stupid to people who "understand". There is a process of learning that is missing from the article. People get good at OOP rather quickly, but there is a point after that in which they just get crazy and that is a perfect example of crazy. You should never teach a noob to do that.

  20. Dubroy.com/blog - Method length: Are short methods actually worse? - March 9, 2009:

    [...] Last year I wrote a post called If this is Object Calisthenics, I think I’ll stay on the couch where I argued (among other things) that making your methods as short as possible is NOT a good idea. My justification was that it just makes the code more complicated: “That which obscures my code is bad.” But this is even better…actual empirical evidence. [...]