Recently I started working in a project for a new software application which development had already started under the leadership of another guy. After a talk with the other people in the project about its purpose and expected features, and reading a quite poor, not up to date documentation, I spent some time inspecting the code itself in the repos, as the architect I used to be, so that I might figure out which was the assumed architecture, the underlying model, and any other details that might complement what I had been told. This was how I realized that the code had been infected by a dangerous disease: overcoding.
The disease explained
What is this software disease that I call Overcoding? Take any project and search for any solution adopted by its developer/s that might be simplified without loss of functionality, performance, user experience, and without any measurable increase of its total cost. If you found it, you may say that the project is infected by overcoding, just a synonymous for useless, wrong efforts in software. As Albert Einstein once said,
“Physics should be as simple as possible, but not simpler.”
A principle that I, among others, strongly believe is applicable to software as well. As it is written in the Agile Manifesto:
Simplicity — the art of maximizing the amount of work not done — is essential
We might learn the same, though in other words, by reading the aphorisms in The Zen of Python:
Simple is better than complex. Complex is better than complicated.
This is because magic in software does not need superfluous lines of code to happen. On the contrary, the best ideas in code often amaze you with its simplicity and economy of resources. I talk about this in another place, but I do not want to avoid this opportunity to emphasize this point again, so key I believe it is in our work.
Even though, this post’s topic is, strictly speaking, the opposite: what happens in the code whenever we fail to follow the principles in the Manifesto?
What happens whenever any feature that could be implemented in a quite simple way, once overcoded, becomes a far more complicated solution just for sophistication sake, a.k.a. the hype? As it happened, for instance, in the aforementioned project, where the architecture was designed not as a direct consequence of the domain requirements and the context the project lives in, but after the vain desire of playing with sexier technologies of a misguided architect.
Overcoding makes the software less understandable, what impacts negatively in its further evolution, and maintenance. This might make it more difficult to test, although this specific aspect of overcoding is not so common because tests usually depend more on specifications that in implementation.
And Overcoding also impacts negatively in costs, since it makes the software harder to deploy, needed of more CPU cycles and infrastructural services to run, and all this results in more money wasted in paid invoices and wages.
In other words, overcoding makes the software inefficient, and more expensive to develop, deploy, maintain and run.
The infection vectors
Why is overcoding happening at all? The fact that the creation of software involves nothing more than letters written in a black or white panel before being written down in something so humble as bytes, makes overcoding extremely cheap. Compare this software production with the product development in manufacturing or pharmaceutical industries, for instance. The material artifacts they produce can easily avoid over-engineering thanks to the control in costs that is in place in those industries, a control that we hardly find in software production, and for good reasons.
There are also other strong active principles that are commonly considered as strongly positive vectors of improvement in software development, but which also have their dark side: the pressure for self-improvement, and the high speed of technology renewal.
I am sure that you’ll agree with me in this: we, as members of the software development community in its widest meaning, are under an enormous pressure of improving our skills continuously: to increase our value in the job market, to increase our reputation inside the same community, to avoid be left behind for obsolete, and, at the end, to improve our self-esteem. All of this to ultimately be more productive at work.
Accelerated technology renewal is also pressuring developers on the same direction. We are obsessed in going forward, in producing the newest architecture for our next project in hand. Unfortunately, it takes a lot of experience to acquire enough taste to notice when some technology, methodology, or existing software fits in, and when it doesn’t. Nothing meaningful happens just because, and so new software comes out of those key features which the current software lacks of, at least at a reasonable cost in its widest sense (implementation, infrastructures, quality code, etc).
Also, as another infection vector, we should recognize that there is some pretending in play here. We love to be mentioned, as a social recognition of our value as members of the community. This pressure might drive us onto implementing more hyped technologies or methodologies in a project in which, simply said, they are not necessary at all, in the seek of educating ourselves or producing something we might exhibit if occasion shows up.
And one more reason for overcoding: boredom. For a developer’s point of view, full of proud with our role combining engineering and creativity, it is sad to admit that a weakness as common as boredom is the antechamber of sharp declines in quality and productivity, but statistics clearly states that it is so. When every aspect in a project (the product, the team, the technology, the architecture, the company, etc) are well known, developers might find a reasonable excuse to keep themselves motivated through exploring other ways to accomplish the same aims.
So, with all these forces pressuring on our teams to produce, as simple as it is, bad software, what could we do to fight them?
Vaccines for the disease
How can we avoid overcoding? Since your team is the most valuable instrument you have to achieve your objectives, to empower your team, to make it grow, should be your first priority ever. These that follow are my suggestions, but I will gladly hear any others from you.
- Implement code reviews, at least before pull requests to master branches can be approved. Make clear as crystal that it is not people the target in code reviews, but the code they produce. And, as a matter of fact, do not focus only on bad practices or improvements; code reviews are a splendid occasion to congratulate awesome ideas as well.
- Use retrospective meetings to discuss on potential refactoring of parts of the code already in the repo. It is hard to align costs and schedules with refactoring, but we are sitting on a very powerful position since we have the user experience quality KPIs and the statistics of reported bugs. So use the quality improvement as one of your tools to justify some refactor or even a new technology or methodology to be used in some all-new microservice to start being developed.
- Since refactoring and pure experimentation are not the same, move experiments to bespoke initiatives (tests of concept, etc.), or to personal projects. You should never allow experimentation, or self-education, in software that is part of a sprint, meaning it is planned to be put into production some day. But your team also need some space to play with other ways to do things, to learn, and, why not, amuse themselves a bit. So, organize things to make it happen, and keep up the perceived fun.
- Make of documentation something alive by appointing solution reviews in public. It gets very difficult to lecture an overcoded approximation simply because you know, in your very heart, that people in the audience will clearly notice it.
In conclusion, the better vaccine to overcoding and have a healthy code is to keep your team healthy: promote good practices, like code reviews and solution reviews, use retrospective meetings to collect refactoring proposals, push to tasks out of sprints any educational or experimentation efforts, and fight boredom. Soon you will see that, as any other disease that might infect your code, overcoding vanishes.