2016-05-11 - This article has been translated into Portuguese by @paulorodriguexv.
Last month, I gave a talk about Object Calisthenics at Clermont’ech’s APIHour #2, a local developer group based in Clermont-Ferrand (France).
I discovered Object Calisthenics almost two years ago, but I wasn’t open-minded enough to give them a try. A year ago, Guilherme Blanco and I were drinking beers in Paris. He told me that Rafael Dohms and him ported the concept of Object Calisthenics to PHP. That was awesome, and I decided to learn, understand, and try these rules. I am now convinced that these rules are really helpful, and that trying to respect these rules help you write better Oriented Object code.
Object Calisthenics are programming exercises, formalized as a set of 9 rules invented by Jeff Bay in his book The ThoughtWorks Anthology. The word Object is related to Object Oriented Programming. The word Calisthenics is derived from greek, and means exercises under the context of gymnastics. By trying to follow these rules as much as possible, you will naturally change how you write code. It doesn’t mean you have to follow all these rules, all the time. Find your balance with these rules, use some of them only if you feel comfortable with them.
These rules focus on maintainability, readability, testability, and comprehensibility of your code. If you already write code that is maintainable, readable, testable, and comprehensible, then these rules will help you write code that is more maintainable, more readable, more testable, and more comprehensible.
In order to follow this rule, you have to split your methods up. Martin Fowler, in his book Refactoring, introduces the Extract Method pattern, which is exactly what you have to do/use.
The else keyword is well-known as the if/else construct is built into nearly all programming languages. Do you remember the last time you saw a nested conditional? Did you enjoy reading it? I don’t think so, and that is exactly why it should be avoided. As it is so easy to add a new branch to the existing code than refactoring it to a better solution, you often end up with a really bad code.
An easy way to remove the else keyword is to rely on the early return solution.
The condition can be either optimistic, meaning you have conditions for your error cases and the rest of your method follows the default scenario, or you can adopt a defensive approach (somehow related to Defensive Programming), meaning you put the default scenario into a condition, and if it is not satisfied, then you return an error status. This is better as it prevents potential issues you didn’t think about.
As an alternative, you can introduce a variable in order to make your return statement parametrizable. This is not always possible though.
Also, it is worth mentioning that Object Oriented Programming gives us powerful features, such as polymorphism. Last but not least, the Null Object, State and Strategy patterns may help you as well!
Following this rule is pretty easy, you simply have to encapsulate all the primitives within objects, in order to avoid the Primitive Obsession anti-pattern.
If the variable of your primitive type has a behaviors, you MUST encapsulate it. And this is especially true for Domain Driven Design. DDD describes Value Objects like Money, or Hour for instance.
Any class that contains a collection should contain no other member variables. If you have a set of elements and want to manipulate them, create a class that is dedicated for this set.
Each collection gets wrapped in its own class, so now behaviors related to the collection have a home (e.g. filter methods, applying a rule to each element).
Basically, the rule says that you should not chain method calls. However, it doesn’t apply to Fluent Interfaces and more generally to anything implementing the Method Chaining Pattern (e.g. a Query Builder).
For other classes, you should respect this rule. It is the direct use of the Law of Demeter, saying only talk to your immediate friends, and don’t talk to strangers.
It is ok-ish to have public attributes in Piece and Location. Actually, having a public property or a private one with getter/setter is the same thing (see Rule 9).
It accesses a Location, then its current Piece, then the Piece’s representation on which it performs an action. This is far from One Dot Per Line.
Then again, you should change the visibility of your attribute. As a reminder, the Open/Closed Principle says that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
The right question is Why Do You Want To Abbreviate?
You may answer that it is because you write the same name over and over again? And I would answer that this method is reused multiple times, and that it looks like code duplication.
So you will say that the method name is too long anyway. And I would tell you that maybe your class has multiple responsibilities, which is bad as it violates the Single Responsibility Principle.
I often say that if you can’t find a decent name for a class or a method, something is probably wrong. It is a rule I use to follow while designing a software by naming things.
No class over 50 lines and no package over 10 files. Well, it depends on you, but I think you could change the number of lines from 50 to 150.
The idea behind this rule is that long files are harder to read, harder to understand, and harder to maintain.
I thought people would yell at me while introducing this rule, but it didn’t happen. This rule is probably the hardest one, but it promotes high cohesion, and better encapsulation.
A picture is worth a thousand words, so here is the explanation of this rule in picture. Note that it relies on Rule 3: Wrap All Primitives And Strings.
The main question was Why two attributes? My answer was Why not? Not the best explanation but, in my opinion, the main idea is to distinguish two kinds of classes, those that maintain the state of a single instance variable, and those that coordinate two separate variables. Two is an arbitrary choice that forces you to decouple your classes a lot.
My favorite rule. It could be rephrased as Tell, don’t ask.
It is okay to use accessors to get the state of an object, as long as you don’t use the result to make decisions outside the object. Any decisions based entirely upon the state of one object should be made inside the object itself.
That is why getters/setters are often considered evil. Then again, they violate the Open/Closed Principle.
In the code above, the getScore() is used to make a decision, you choose how to increase your score, instead of leaving this responsibility to the Game instance.
A better solution would be to remove the getters/setters, and to provide methods that make sense. Remember, you must tell the class to do something, and you should not ask it. In the following, you tell the game to update your score as you destroyed ENEMY_DESTROYED_SCORE enemies.
It is game’s responsibility to determine how to update the score.
In this case, you could keep the getScore() as you may want to display it somewhere on the UI, but keep in mind that setters should not be allowed.
If you don’t feel comfortable with these rules, it is ok, but trust me when I tell you that they can be used in real life. Try them in your spare time, by refactoring your Open Source projects for instance. I think it is just a matter of practice. Some rules are easy to follow, and may help you.