Don't try to avoid essential complexity

When I first stumbled upon eXtreme Programming, one of the concepts that really blew my mind is the famous YAGNI principle.

Lots of junior developers (and I include myself few years ago) are passionate about programming, and always want to show their skills. In some cases, this could lead to some very complex solutions to simple problems. Enterprise application development in the 2000s was full of culprits, and if you’ve been lucky enough to don’t know, you can have a look at FizzBuzzEnterpriseEdition. While this is a (rather funny) joke, unfortunately the problem is not that uncommon, specially if you work with legacy code.

The YAGNI (You Ain’t Gonna Need It) principle could be translated in “do the simplest thing that could possibly work”. It’s a methodology that - applied together with continuous refactoring - allows engineers to build software that does exactly what’s required, nothing more and nothing less (ok, I’m not talking about bugs here).

While the principle is in my mind one of the most interesting ideas that came up with XP, in my daily life as a developer I see cases when this principle is poorly applied.

In our quest for trying the simplest thing that could possibly work, sometimes we try to avoid essential complexity. Essential complexity is complexity that is tied to the problem itself. As a basic example, we know that the complexity to order a generic of numbers the complexity is Ω(nlogn) here’s the proof. Another example that falls into essential complexity is taking in consideration the CAP Theorem when dealing with distributed systems (and to keep it simple, I’m not considering eventual consistency).

Ignoring essential complexity is not a way of doing the simplest thing that could possibly work, because what’s done ignoring essential complexity will not work. We may find things working for a while, and our tests may even pass, but we know that our code will eventually fail. One of the cases that come to my mind is currency representation. To mitigate this in my experience we should study the domain of the problem and the technologies / algorithms we intend to use to solve it - this will also allow us to make a better informed choice.

However we still want to try and avoid accidental complexity. This complexity is introduced by the code we write - to get an ironic example of what I mean pick any item from how to write unmaintanable code (p.s. Google Chrome users, you’ll get a security warning if you open that link - however it’s just fine with any other browsers). We don’t need all of that. Writing simple and readable code should always be amongst our top goals.

But simple doesn’t mean simplistic.