Object Calisthenics In JavaScript - An Introduction

Posted May 4, 2012 at 10:30 AM by Ben Nadel

Tags: Javascript / DHTML

Several years ago, Brian Kotek introduced me to the concept of Object Calisthenics. Object Calisthenics is an exercise defined by Jeff Bay to help programmers think very critically about their application design choices in an object-oriented context. I attempted this exercise a long time ago; but, I was quickly flustered by my lack of understanding. Now, a few more years of experience under my belt, I thought it would be an exciting exercise to try again. While I see myself as being very technically-capable in programming, I clearly lack a strong understanding of Object Oriented Programming (OOP). I'm hoping that this exercise will help me gain clarity and kick the bad habits that I have accumulated from years of procedural programming.

Some quick background information - what's the point of Object Calisthenics? Here is an excerpt from Jeff Bay's paper on the subject:

We've all seen poorly written code that's hard to understand, test, and maintain. Object-oriented programming promised to save us from our old procedural code, allowing us to write software incrementally, reusing as we go along. But sometimes it seems like we're just chasing down the same old complex, coupled designs in Java that we had in C.

Good object-oriented design is hard to learn. Transitioning from procedural development to object-oriented design requires a major shift in thinking that is more difficult than it seems. Many developers assume they're doing a good job with OO design, when in reality they're unconsciously stuck in old habits that are hard to break. It doesn't help that many examples and best practices (even Sun's code in the JDK) encourage poor OO design in the name of performance or simple weight of history.

The core concepts behind good design are well understood. Alan Shalloway has suggested that seven code qualities matter: cohesion, loose coupling, no redundancy, encapsulation, testability, readability, and focus. Yet it's hard to put those concepts into practice. It's one thing to understand that encapsulation means hiding data, implementation, type, design, or construction. It's another thing altogether to design code that implements encapsulation well. So here's an exercise that can help you to internalize principles of good object-oriented design and actually use them in real life.

In the above PDF, Jeff Bay goes on to describe the 9 rules of Object Calisthenics:

  1. One level of indentation per method.
  2. Don't use the ELSE keyword.
  3. Wrap all primitives and Strings in classes.
  4. First class collections (no simple Arrays).
  5. One dot per line (don't violate the Law of Demeter).
  6. Don't abbreviate names.
  7. Keep all classes less than 50 lines.
  8. No classes with more than two instance variables.
  9. No getters or setters.

This sounds tough! But, that's what makes it exciting. For this exercise, I want to do something that is non-trivial; but, also something that is not so complex that it takes forever to finish it. After a few days of mulling over ideas, I decided to go with the concept of a "Match Maker" (as in, Relationships). This gives me the opportunity to look at polymorphism, collections, and behaviors.

To get started, I've created a GitHub repository for this exercise as I am sure it will require many iterations to get right. Very exciting! Wish me luck :D


You Might Also Be Interested In:



Reader Comments

May 4, 2012 at 1:42 PM // reply »
49 Comments

>> Don't use the ELSE keyword.

Eh?

So it's expecting people to write:

  • if ( something )
  • {
  • ...
  • }
  •  
  • if ( ! something )
  • {
  • ...
  • }

?

>> Keep all classes less than 50 lines.

That sounds like an arbitrary limit. :/


May 4, 2012 at 2:18 PM // reply »
2 Comments

@Peter Boughton. The Else restriction isn't so that you use another if with !, it is trying to get you to use polymorphism. The source link has a bit more of an explanation Don't use the ELSE keyword. This one is tough. We're very used to using if/else or switch/case. But good OO designs rely on polymorphism in place of conditional logic.

50 lines is definitely arbitrary, but the point is trying to ensure that each class is doing one thing and one thing alone. In js I think 50 lines is reasonable, but if you're in something like java you should probably avoid counting some of the boiler plate code like imports.

Great post Ben. I love seeing the different forms of practice that people use to improve their development skills.


May 4, 2012 at 2:38 PM // reply »
11,246 Comments

@Peter,

I believe the main goal of the exercise is to help you think outside of your comfort zone. It's kind of like the idea of never saying "No" to things. Clearly, that's crazy! There's lost of things you *should* say No to. But, the point is to be more open than you used to be.

This, to me, is the same way. By going extreme, you will necessarily have to change the way you think about things. Some of things may be good; some may be bad. I can't know until I try.


May 4, 2012 at 5:09 PM // reply »
11,246 Comments

I'm 1-hour into this... and already I have a lot of anxiety!!! This stuff is hard!


May 6, 2012 at 1:45 AM // reply »
1 Comments

There is a point where using more Polymorphism/ creating more classes actually hurts more than hinders a program. It might allow for more scalability, but there are a lot of areas where building as much scalability in as possible is futile because it'll never be changed. Besides, more often than not it hurts performance, though usually negligibly. This whole thing seems more like a farce designed to hurt people's brains rather than a practical exercise.


May 7, 2012 at 3:36 AM // reply »
1 Comments

I think I'll give this exercise a try. Though I'm not realy sure I completely understood it...


May 7, 2012 at 5:18 PM // reply »
11,246 Comments

@Joe,

I think it is definitely designed to "hurt people's brains." I think that's the point. It's like shocking the heart to get it back to a good rhythm - the benefit is not in the shock itself, but rather in the resultant adjustment. As long as this helps me expand my understanding, it will be a worthwhile endeavor.

@All,

I tried to work on this over the weekend. Here is the code and reflections that I came up with:

http://www.bennadel.com/blog/2375-Object-Calisthenics-In-JavaScript-My-First-Attempt.htm

I am looking forward to trying it again. There were parts that didn't necessarily agree with me; but, I really enjoyed the way it challenged me to think hard about where behavior should reside.

@Peter,

Glad you like the idea. I definitely recommend it!


May 9, 2012 at 7:33 AM // reply »
7 Comments

Good stuff as always!

Here is a helpful link for the if else refactor - using polymorphism:

http://sourcemaking.com/refactoring/replace-conditional-with-polymorphism


May 14, 2012 at 9:36 AM // reply »
11,246 Comments

@Steve,

I've been reading through the SourceMaking.com websites. It's pretty awesome! I have never seen this before, but their articles on refactoring (and the like) are super insightful. Thanks so much for passing this along - I'm loving it!


Jun 11, 2012 at 6:18 PM // reply »
1 Comments

@Peter,

The idea of avoiding ELSE is that you decouple these actions from their relative context, making them usable anywhere. So as opposed to your example you could write:

  • function doSomethingForThisCondition(){...}
  •  
  • function doSomethingForThatCondition(){...}

Or, better yet, you could design a set of subclasses whose

  • function doSomething(){...}

does something completely different.

  • class Human extends Mammal{
  • function communicate(){
  • speak();
  • }
  • }
  • class Dog extends Mammal{
  • function communicate(){
  • bark();
  • }
  • }

If you're focusing on Inversion of Control and value loose coupling, this makes the most sense.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 24, 2013 at 4:45 PM
Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion
@Ben I have been lurking your site for quite some time, and haven't stepped up to comment until today. Thanks for all the great info - keep it up! @Adam I believe you are mistaken... as the commen ... read »
May 24, 2013 at 11:21 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, Ha ha, let's us never speak of justifying "##" notation again :P ... read »
May 24, 2013 at 11:18 AM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@Ben, Ah, so it was indeed how I vaguely remembered it to be: A direct assignment value = users.id[ i ] causes value to retain the sticky datatype of the query column. Although unnecessary in ... read »
May 24, 2013 at 9:11 AM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Brandon, Hi, No, I haven't been able to do that. I have just kept it as it is. ... read »
May 23, 2013 at 9:52 PM
Preventing Links In Standalone iPhone Applications From Opening In Mobile Safari
@Muhmmadibn Did you figure out a solution to launching PDFs? I am running into the same issues myself. There is no way to close the PDF or go back once you launch it. Thanks in advance! ... read »
May 23, 2013 at 6:06 PM
The Girl Who Broke My Heart, And Made Me A Better Person
Good day,ladies and gentle men, my name is Dr AMADI the great spell caster in Africa, i have help so many people for different kind of problems,who say there is no solution to problems on earth, that ... read »
May 23, 2013 at 4:26 PM
ColdFusion QueryAppend( qOne, qTwo )
@Heather, Glad people are still getting value out of this! ... read »
May 23, 2013 at 3:49 PM
Strange Interaction Between DeserializeJson(), ArrayContains(), And Database Values In ColdFusion
@WebManWalking, I meant the code at the bottom (not the video). I did try to experiment with an intermediary variable, like: value = users.id[ i ]; arrayContains( userIDs, value ); ... but t ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools