Have you ever disagreed with conventional wisdom? How do you know when it is sound advice? Are they ever wrong? Does context matter? These are a few questions that have been swirling around my mind lately.
There's a lot of patterns in software engineering that many endorse. On the surface they sound reasonable, but I struggle accepting most of them:
- Don't repeat yourself (DRY)
- Convention over configuration
- Write automated tests for your projects
- Avoid boolean args for functions
- Too much indirection should be avoided
- Explicit is better than implicit
- Keep is simple, stupid (KISS)
- Reduce levels of nesting
Some of these I adhere to and think about regularly when writing code. Some of them I think about but mostly ignore. There are even some that I reject.
I think DRY is one of those concepts that does more harm than good most of the
time. Being over-zealous about making sure you don't repeat yourself is a recipe
for hard-to-read code. We trade copy/pasting snippets of code with a rats nest
of modular dependencies. Engineers don't know how to organize their code. I see
it in every project, exemplified in the dreaded
util module, a black hole for
every lost function.
I prefer the WET approach: Write Everything in Threes. Copy/paste at least three times before creating a dependency. In my heart I must admit, this is still a disciple of DRY but it's less dogmatic.
Another reason why I don't like DRY is because it creates a mindset to always find the common abstraction point between different sets of functionality, even if they're disparately related. This mindset is a virus plaguing software engineering and creates some of the most difficult code to read and maintain.
Ghost in the machine
This leads to my next rant that I see all-the-time which is the tendency to over-engineer everything. We are a hammer and every problem is a nail that can be solved by the act of thinking. We fall into the trap of overthinking every scenario because we are paid to poke holes in systems and then patch them before it gets to the user.
I struggle with this one a lot. I see the bias in all of us, I see the struggle wash over us like the tide rising on the beach. "Resist the urge" is what I tell myself.
Tests waste a lot of time
This one stings. I've written so many automated tests, but how many have actually caught something important? A couple dozen? Juxtapose that against the amount of time I've spent writing and maintaining tests and the economics of the situation feel grim. This is especially true when you don't even know the project is going to last longer than a few years.
What is the point of writing an automated test? They ensure our code works as expected as well as prevents us from changing code that would break previous expectations. They are also a form of documentation.
What's the alternative to automated tests? Manual tests. All of these features of automated testing apply to manual testing. The main difference is how long they take to perform and maintain. Which one saves more time while also preventing more regressions? That's an empirical, quantifiable question as well as the basis for my argument. It's a calculation one must perform in order to determine whether automated tests are worth it.
If a test never fails, is it a good test? If I have to change a test everytime I change the implementation, is it a good test? Writing good tests is really difficult.
This is where I think context matters. If you're writing a library or an API with clear inputs and outputs, then yea, tests are great.
If you're writing complex UI apps that are being manually run all day long, then I'm not so sure about the ROI. The current trend is to focus primarily on integration tests for the FE. Those require a lot of infrastructure just to get the test setup properly, not to mention dealing with the actual thing you want to test. The tests are large, confusing to read, and usually strung together as an after-thought. Further, when one grain of sand deviates from when the test was originally written, the test fails and so does your productivity for the day.
Ultimately I think automated tests are over-valued and we spend way too much time writing them.