Object Calisthenics: One level ! But how can we manage to exit a loop ?
Let’s start by an example to explain our problem. Suppose we have the following static method — static just for this example purpose — :
This code reveals an immediate return whenever the condition is truthy. It is very simple and readable, however we have two levels of indentation that violate Object Calisthenics rules.
A similar problem could occur with continue or break. So, how could we exit a loop properly when we should only have one level per method?
Object Calisthenics rules tell us what to do, not how to do!
Performance
Before introducing any solutions, let’s first have a look at this method performance* called twice with 50 000 elements :
In order to address the OC violation rule, I have came up with two solutions:
1. Using array_reduce
The idea behind using array_reduce is to return a boolean value after traversing the array and delegating the test inside the previous loop — foreach in our case — to the reduce callable function as follows:
Although array_reduce traverses the whole array, we still have a linear function with O(n) complexity.
Performance
For the same number of elements — 50 000 — and the same assertions, the method performance is still acceptable:
array_reduce is used for this special case, but for other cases, we can utilize array_filter or array_map. In other languages, like Javascript, we can benefit from Array.prototype.some().
2. Using recursive function
In some cases, using a recursive function that traverses the array would be a perfect solution:
The recursion occurred after diminishing the data array — using array_pop in our case — and if both conditions are met.
In the end, even though all elements weren’t utterly traversed and complexity remained O(n), recursion occupied a lot of space, which affected method performance :
Conclusion
I recommend array_reduce (or any built-in function) in almost all cases over recursive methods. Using this kind of pattern makes the code more fluent and cleaner.
Don’t hesitate to give me your feedback or contact me on Twitter @elie_nehme
*https://3v4l.org is an online shell that allows us to run PHP code in different versions. It is not a real tool for application benchmark.