Ready to up your coding game? Object Calisthenics will help you create code that is cleaner, more flexible, more agile, and more reusable.

What Are Object Calisthenics?

Object Calisthenics were first introduced by Jeff Bay in The ThoughtWorks Anthology[3], a compilation of essays on software engineering. If this is your first time reading about this concept, I suggest you use this article as an introduction, as these are not principles you necessarily apply on a daily basis, but rather principles to apply on a 1,000-line project as an exercise to force yourself to adopt a different approach to designing software.

Keywords: Clean Code, SOLID, Object-Oriented, Software Design

SOLID and Object Calisthenics

The primary objective of Object Calisthenics is to apply certain SOLID principles [2]. SOLID principles are basically a set of best practices to increase the quality of your code by focusing on maintainability, readability, testability, and comprehensibility [1].

There is a strong correlation between SOLID principles and the practice of Object Calisthenics. SOLID principles focus on dependency management, and Object Calisthenics focus on a solution that makes dependency management possible, providing steps to achieve this goal. The main purpose of Object Calisthenics is to make designs easier to understand, maintain, and extend [4]. 

The SOLID principles are:

  • S – Single Responsibility Principle
  • O – Open/Closed Principle
  • L – Liskov Substitution Principle
  • I – Interface Segregation Principle
  • D – Dependency Inversion Principle

While the Object Calisthenics principles are:

  1. Use only one level of indentation per method
  2. Don’t use the else keyword
  3. Wrap all primitives and strings
  4. Use only one dot per line
  5. Don’t abbreviate
  6. Keep all entities small
  7. Don’t use any classes with more than two instance variables
  8. Use first-class collections
  9. Don’t use any getters/setters/properties
Object Calisthenics Principles

Let's review each principle in a little more detail [3].

1. Only One Level of Indentation Per Method

This principle tries to enforce methods that do exactly one thing, as methods with multiple levels of indentation often also have multiple levels of abstraction. By writing smaller methods, you might notice more opportunities to reuse your code and eliminate duplicated code. For example:

2. Don't Use the ELSE Keyword

This principle is by far the easiest to apply on a daily basis and is as simple as using early returns to avoid else statements. The else statement is a common concept in many programming languages, and most of the time, we see a complex nested conditional statement. It's easier to just add another instead of refactoring all that logic. Using early returns and avoiding the else keyword can help you create more readable code.

3. Wrap All Primitives and Strings

While using primitives, make sure this decision is either about performance or the data lacks behaviour. If the data you are storing in a primitive actually contains behaviour, it will end up scattered over the codebase. Creating an object instead helps to represent this intention and makes it easier to read wherever the object is used.

In the example below, ZIP code does not have the rules in the object, so it must be validated in all referenced objects:

Applying this rule, the object will be:

4. One Dot Per Line

Using only one dot per line will make your code more readable by eliminating chain method calls. Nevertheless, it doesn’t apply to Fluent Interfaces or anything implementing the Method Chaining Pattern [1].

5. Don't Abbreviate

As every programmer knows, one of the hardest challenges we face every day is naming things. There is a temptation to abbreviate variables, methods, or column names just because it will make names "shorter" or "cleaner."  But the key thing to consider is context. For example, if we have a class called Order and a method to ship it, why would we name it shipOrder if it's already a method of the Order class? Naming it ship will make it cleaner and easier to read when it is used, as there will be no redundancy; i.e. order.ship() is better than order.shipOrder(). Considering context will help you shorten names without abbreviating or sacrificing clarity.

6. Keep All Entities Small

The official Object Calisthenics recommendations are to use classes smaller than 50 lines of code and packages smaller than 10 files. This is pretty strict, but the takeaway is that smaller classes tend to be more cohesive, as well as easier to read and understand.

7. Don't Use Any Classes with More than Two Instance Variables

This rule is the hardest one to follow, but the benefits are high cohesion and better encapsulation. Limiting yourself to only two instance variables is not an achievable goal for big projects, but the intention is to force you to decouple your classes a lot.

8. Use First-Class Collections

This rule is rarely used. It centralizes the behaviors related to the specific collection in a class, and each collection gets wrapped in its own class.

9. Do Not Use Getters/Setters/Properties

This is a really strict rule with a great purpose. It will force you to follow the "Tell, don't ask" principle of object-oriented programming, and it's easy to notice the beneficial effects because you'll have a hard time writing logic where it shouldn't be written. Because of this, the behaviours will end up being inside the objects they belong to.

Conclusion

These principles are not a cure-all. Using them will not mean that you avoid design issues, but it will make your code more flexible, more agile, and more reusable.

Keep in mind that you do not need to follow all of these rules in your daily routine. Instead, start by trying to apply rules 1-5 and rule 9. You will see a big difference in your code. The other rules are rarely used in medium/large projects or legacy projects.

 

This article was co-written by Lucas Garcia.

 

References

[1] W. Durand. Object Calisthenics. Jun 13th 2013. Last accessed: Jan. 18th 2021.

[2] R. Cruz. Desenvolva um código melhor com Object Calisthenics. Aug 8th 2018. Last accessed: Jan. 18th 2021.

[3] Steinberg, Daniel H., ed. The ThoughtWorks® Anthology: Essays on Software Technology and Innovation. Pragmatic Bookshelf, 2008.

[4] S. Watts. The Importance of SOLID Design Principles. Jun. 15th 2020. Last accessed: Jan. 18th 2021.


Author

Rita Pissarra

Rita Pissarra is a Software Engineer at Avenue Code. She is a professional in love with her work. She is very careful with her decisions and attentive to details to build the best software possible. She has been studying/working in IT since 2009 and loves it so much! Her hobbies include dancing ballet and street jazz, and she loves manga too; she is especially a fan of Itachi.


How to Save Time and Effort Using The Test Pyramid

READ MORE

It's Time to Migrate: JUnit 5 is Better than JUnit 4

READ MORE

The Three Automated Tests Every React.JS Developer Should Know

READ MORE