Rage against flexibility

Often while I am reviewing code I stumble upon pieces that are trying to do way more things than the requested feature demands. We all have been there, either reading or writing code that does more things than the ticket/issue we are working on requires. Many times we try to predict the future, because we guess that touching this specific part of the system now is easier than doing it later when a new requirement comes up. In my opinion this mentality is completely wrong and can lead to slowing down a team instead of moving things faster.

Let’s image that your boss asks you to create a component that accepts an array and renders a list of items, and you guess (or even know) that in 3-4 months you will have to support nested lists. So instead of writing something like this:

The developer writes something like this:

Just a simple guess from the developer increased the Cyclomatic Complexity of the component. A component that could have cyclomatic complexity 1 (1 edge – 2 nodes + (21) = 1), became a component that has complexity 2 (4 edges + 4 nodes + (21) = 2).

Although this is a very simple example (usually in reallity we create even more complex components/modules/functions based on our assumptions) it indicates how a simple guess by the developer can increase the complexity of a small piece of the codebase.

Simple things should be simple and complex things should be possible -Alan Kay

 

Let me explain why I believe that this kind of phillosophy (of adding unnecessary functionallity) is wrong:

YAGNI (YOU AIN’T GONNA NEED IT)

YAGNI is one of the principles Kent Beck defined when he introduced the extreme programming (XP) that states that a programmer should not add functionality until is absolutely needed. Most of us work in enviroments that practice the agile methodology, requirements costantly change, we cannot predict the future, its very likely that the code you wrote because you assumed a future requirement wont be needed.

THE COST OF BUILDING

That is obvious, as developers we should deliver as fast as possible. Spending time on building things that are not nessecary slow us down. The code that we introduce has to be reviewed and tested as well.

THE COST OF MAINTAIN AND DEBUGGING

Don’t be proud for the number of lines you wrote. Be proud of the number of lines you managed to avoid writing.

“One of my most productive days was throwing away 1000 lines of code.” – Ken Thompson

 

There is this “funny” advertisement by Mercedes that brags about the number of lines of code their car has. To me this doesn’t sound like something impressive, it sounds like something scary.

Be shy about the code you write, its the code that your team has to read, debug and maintain in the future.

THE COST OF GOING UP AND DOWN TO A LEVEL OF ABSTRACTION

Often developers introduce unessecary code, creating abstractions instead of simple functions because they assume that adding an abstraction will make the code more flexible. In my experience this is not the case, first its very difficult to predict how your abstraction should be when you only have 1-2 cases on how the lower level layers will be and second you cannot predict how the shape of the application, the external APIs or the feature requirements will be, and in these cases developers usually add more complexity to their abstractions to make them support the new concrete lower level, or they create a new abstraction on top of the old one. Too abstract: too much mental overhead to understand, less room for optimizations. There is a great talk by Cheng Lou “On the spectrum of abstraction”, I would advice you to watch it.

FINAL THOUGHTS

In my experience building something that you may won’t need is more expensive than not making your system as flexible as possible from the bare beginning. Ditch the flexibility out of your code, keep it simple, it is cheaper, faster and more reliable.

“Simple things should be simple and complex things should be possible.” – Alan Kay

 

Make your systems/components/modules/functions easily extendable, with as less as possible preconditions and as less as possible outputs. Don’t introduce abstraction that you dont need yet, wait to have 3-4 concrete cases until you create your abstraction.

“A good design is not the one that correctly predicts the future, it’s one that makes adapting to the future affordable.” – Venkat Subramaniam

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *