Is Good Enough, Good Enough? (Part?1)
“Perfect is the enemy of good.” - Voltaire
This is a two-part article, and this is the first part. You can find the second article here: Is Good Enough, Good Enough? (Part 2)
I used to be a perfectionist. I even thought that this was the only way to be. People who weren’t like me were obviously doing a lousy job. They just didn’t care.
Whenever I got involved in a new feature, I had very high expectations of myself and my work. I wanted to know all the details, cover all the edge cases, and make sure that the solution was scalable and extensible. I’ve spent a huge chunk of time outlining the perfect solutions that would cater to all current and future needs. It had to be perfect.
And then, when I started the actual implementation, I noticed I hadn’t thought of a legacy chunk of code that had a cardinal role in the feature. I missed a use case that affected my perfect plan to a non-negligible extent. I also realized that the library I was planning to use simply didn’t have a piece of functionality that I assumed was there.
I had to scrap my work and go back to the planning board to make a New Perfect Plan. This time I was even more diligent. But, obviously, something similar happened again.
That made me think: Am I chasing something that is not achievable? And more importantly, if it’s achievable, is it even preferable? Let’s explore this.
Why Perfection is a?Myth
But first, what is a perfect engineering solution?
Sounds good and reassuring, right? It’s an engineering panacea. It gives us this nice, accomplished feeling.
However, the perfect solution falls apart when we consider TIME and REALITY.
Let me explain what I mean.
Customers Don’t Need Perfection
One of the most prevalent misconceptions is that customers are only satisfied by perfect systems. However, that’s not true:
Early Feedback is?King
Working relentlessly on the perfect solution robs us of early feedback. In my opinion, feedback is of key importance. Delivering something in a month has a clear benefit over delivering the perfect solution in a year.
Better to figure these out early, right?
Requirements are not?Static
Contrary to popular belief, requirements are seldom static. Requirements serve as guidelines, but as more and more information becomes available, those requirements will very likely change.
I’m not implying that one should just ignore requirements. I’m just suggesting considering them as flexible constraints to development. And as Yoda once said, “Train yourself to let go of everything you fear to lose.”
I’ve seen my share of projects where we thought a set of requirements were paramount, but we ended up with something completely different. Something completely different that served our customers much better.
领英推荐
Some Requirements are More Important than?Others
Loosely connected to the previous point, in most cases, there’s a clear order of importance between the requirements. Some of them are must-haves, others are should-haves, and lastly, there’s a list of nice-to-haves.
The Pareto Principle (AKA the 80/20 rule) largely applies: Often, 80% of the value comes from 20% of the effort. Focusing on that crucial 20% can deliver significant value quickly.
And again, we might realize earlier that delivering the most important features is enough and makes the customers perfectly happy. No need to implement the rest.
Time to Market is Important
Often, there can be a competitive advantage gained from being early or even the first to market with a piece of functionality.
Creating the perfect solution with all the bells and whistles rarely allows us to be in that position.
Getting there early with limited functionality or a non-perfect user experience is often worth it because it could drive serious profit and could also come with a good deal of early feedback from actual users.
It’s OK to Fail (Sometimes)
Engineering types (myself included) have a hard time accepting that our amazing solutions could fail in production. We tend to program guardrails to handle all the error cases that we can think of. And yet, achieving perfection in error handling is hardly feasible. I’d argue that after a certain level, it becomes disproportionately harder and harder to handle possible error scenarios. I’d also argue that we shouldn’t?—?customers can tolerate an error from time to time unless it makes their main use case impossible. So we should be OK with living with a solution that can fail from time to time.
Of course, I’m talking about software that is not life- or mission-critical. In those cases, by all means, be as diligent with the error handling as humanely possible.
We Cannot (Always) Predict the?Future
Engineers often think they know what will happen in the future. They feel like they have a very good understanding of how the software will develop over time. They feel like they know in what ways they will need to extend the application.
However, in reality, this is rarely the case.
Amazingly architected, clever, extensible solutions can fall apart even from a single sentence of a new requirement. I’ve seen this several times.
Reality can hit hard, right?
The Psychological Toll of Chasing Perfection
If we step back a bit, chasing perfection also impacts our psyche. When I think about perfection, a huge and complex project comes to mind with many strict and complicated requirements. It might seem like a huge obstacle that is almost impossible to overcome. Perfectionists also often consider anything that is not perfect a failure. And with the high likelihood of not getting there, this can result in some subconscious anxiety and/or procrastination.
But What is “Good?Enough”?
I have avoided defining what “good enough” is so far. While I have an intuition of what it might be, I researched what the Internet thinks. So here’s a working definition that captures my thoughts perfectly.
“Good enough” software is software that:
To preempt the critique, “Mark, are you suggesting that we should cut corners and ignore our engineering best practices?”, here’s what “good enough” software is NOT:
Summary
In this article, I’ve talked about what I consider perfection from a software engineering perspective. I’ve also brought several examples to justify why I think perfection is neither achievable nor desirable. I’ve also given a definition of what I think “good enough” is in the software engineering domain. In the next article, I will talk about the actual engineering practices we can use to avoid chasing perfection while still delivering an awesome solution.