As head of engineering I’m always looking for ways to deliver more quality, less bugs, maintainable code, scalable features …

In this endless quest we developed internal tools (ex. Gazebo, a tool that orchestrates the flow between pivotal tracker, github and our development, staging and production environments), implemented processes (ex. code review for each pull request) and adopted external tools (ex. gemnasium to keep an eye on the external libraries we use).

One of the tools we like the most is Code Climate, a tool that does automated code reviews and scores each project between 0 and 4 based on code quality (complexity, length, repetition, …).

From the start, and mostly automatically, the team started to pursue the perfect 4.0 score and getting there or really close in every project. This seemed great until I started to notice a troublesome pattern…

Whenever I exercised my programming knowledge trying to debug some issue or reviewing a pull request I started having real trouble following the code flow…

Where is this method defined? How the hell is this method returning X when there’s no way it could looking at the code? … Oh it is redefined in the sub-class… ah this one is inherited from the parent…

I almost always had to go trough complicated hops (almost leaps of faith) until I could finally find the execution flow.

Why was this happening?

One of the most penalising “defects” CodeClimate finds is code repetition, in the same class or between classes.

To achieve the highest score, most of the times without thinking that much about consequences, we started to apply patterns to avoid any kind of repetition… the ultimate dry code!

This was the cause.

Why is this such a problem?

By avoiding repetition we were creating extremely complex code. Not the kind of complexity CodeClimate measures like big methods (lot’s of lines of code) or big classes ( lot’s of methods in a class) but a kind infinitely more dangerous, code that was extremely hard to understand.

The fact that using complex code structure in a feature implementation is bad, is a straight forward conclusion.

The conclusion that many times isn’t that straight forward, is that the work done while implementing a feature is actually a really small fraction of the cost that feature represents.

Most of the cost will be diluted along the feature lifetime in the form of maintenance, communication, training, ...

Other misconception is the fact that maintenance cost of a specific feature is only referring to interventions made directly on the code that implements that feature.

Any added feature adds complexity to the whole system. To all the other product features.

Anyone needing to debug, add functionality, increase performance, … will have to deal sooner or later with everything added into the system.

Where I’m trying to go is: scalability, performance, cleverness, succinctness … are 99% of the times less important than making code that is easy to understand.

Easy to understand code is what every developer should strive to achieve.

How in my teams we try to do this:

- No code goes into production without being peer reviewed;

- Make it clear in the code review guidelines that code simplicity is the main goal;

- CodeClimate scores are important, but secondary to making code that is easy to understand;

- Whenever theres a bug, we try to get someone other than the one who developed the feature to correct it;

- When reviewing or correcting bugs in someone’s code and you find code difficult to understand, refactor it and write down the complexity problems you found;

- Make time to review with the team all the complexity patterns that where found and define the anti-patterns.

Any other ideas ?