As software engineers, our relationship with best practices is an evolving one. We start off unaware of what they are. One day, because someone told us or because we read about it somewhere, we discover them. This is usually where we start to revere them as some kind of holy scripture. The cleaner our code gets, the more obsessed we become. For many of us, it can take a while before we open our eyes again to the cold, hard truth: best practices are nothing but tools. Good tools, but not always the most appropriate for the job.
Take DRY for example. Most may know its meaning1, but how many wondered why it came to be? DRY is the core principle the authors of The Pragmatic Programmer came up with after years of struggling with hard to maintain, entangled code bases. It is a concrete solution to a concrete problem, and it involves abstraction, which also has drawbacks2.
Best practices are in fact just that: experienced programmers’ solutions to recurrent problems, stripped of their context and boiled down to an easy to remember, catchy phrase. They are not golden rules, but trade-offs. They come with less drawbacks than advantages - they are best practices after all - but it is no excuse to not weigh up their benefits and costs before adopting them. And for that, it is often necessary to go back to their origins, and understand the problem they were trying to solve in the first place.
But if the real value of best practices lies in knowing their costs and benefits, why do we always teach them in a simplified, dumbed-down form? Of course, the most obvious answer to that question pertains to our brain’s limited storage space. It is easier to remember a three letter acronym than a full explanatory paragraph! But I feel like our love for best practices is also deeply anchored in our subconsciousness.
Developing software is a complex and mentally taxing task, that often involves spending hours pondering over what choice to make. Worse yet, when we finally take a decision, we often do so with doubt lingering in our minds: did we really chose the right thing? In contrast, best practices seduce us with the promise of simplicity, stability and certainty. By blindly following them, we leave the responsibility of making decisions to a greater authority (the people who came up with said best practice) and assume the more relaxing role of simply applying pre-made rules3. Besides, because their formulation is so simple, best practices also easily translate into metrics. We then turn those metrics into targets - another of our little weaknesses4 - and reaching those targets ultimately grants us what we are longing for: peace of mind (“I reached 100% test coverage! My code must be safe!“). As we all know deep down, this is but a mirage. But this false sense of security can make us dangerously complacent. Reaching 100% test coverage does not guarantee that our code is bug free, and should not be an excuse to let our guard down!
Obviously, I am not saying best practices should not be followed. They are valuable advice from the wise software engineers who came before us. But I do believe that we should always remember that they are not absolute truths.
As always, shoot me a message or tweet @nicol4s_c if you want to chat about any of this, if you spotted any mistakes or typos, or if you’d like me to cover anything else! Have a great day :)
- Don’t Repeat Yourself, a.k.a. avoid duplication and redundancy. [return]
- If you’re curious about the cost of abstraction, I highly suggest you watch this talk by D. Abramov [return]
- In a way, it is similar to the infamous “We’ve always done it this way”: saying “let’s do this because it is a best practice” without understanding why is essentially appealing to authority, which is a logical fallacy. [return]
- “When a measure becomes a target, it ceases to be a good measure” (Goodhart’s law) [return]