Perfect is the enemy of good

general

Perfect is the enemy of good.

Better a diamond with a flaw than a pebble without.

These are the quotes handed to me when I googled what I personally thought the quote was (“Perfection is the enemy of done”). Honestly, I don’t know if they’re right; they sound good, and I pasted them from Wikipedia, so there must be something true about them, right?

Anyway, I wanted to write down my own thoughts on aiming for perfection in Software Engineering. This is a subject I’ve discussed with one of my teammates as a means to improve themself; however, I don’t think I covered it particularly well with them. Hopefully, in this post, I’ll clarify and condense my thoughts, making it easier to provide feedback on this topic in the future.

The way I see it, aiming for perfection isn’t wrong. It’s an excellent destination to aim for at the start of a change, bug or feature. You want to create the best solution possible. If you don’t think like that, then you’ll never be able to make significant strides in improving whatever you’re working on.

However, aiming for perfection can lead you down a dead-end. You become so consumed by how you must reach the destination you envisioned that you become blind to all the signs telling you otherwise. Overlooking all the different routes you can take. Paying no attention to the directions that others give you. Where you finally reach the dead-end that your choices lead you to, and instead of turning back around, you pull out a shovel and try to dig a tunnel past this blockade. Unfortunately, you’re standing on concrete, and there is nothing left to try. Leaving you frustrated, anxious and maybe even distraught as you were so sure you were right, and it still went so wrong.

Now, I’m going to end my short stint of creative writing and really get to the points I was trying to make in the paragraphs above and how they relate to Software Engineering.

When you are working on a feature, there is a good chance you’ll produce a design or have an idea of what you want to do before you start coding. At this point, you might have decided the structure of your solution, decided to introduce another tool, library or framework, or even thought of specific code you want to write.

This is good; thinking ahead and ironing out potential issues is hugely beneficial.

Unfortunately, the likelihood of you perfectly identifying all the potential holes in your design is pretty low. Something almost always goes wrong; you could introduce an unforeseen circular dependency, the library you brought in might not work how you thought it did, or the code you wanted to write doesn’t even compile. All of these could throw you off.

Despite all these pitfalls, you could still think you’re on the correct path and double-down until you reach a dead-end. At this point you can feel defeated, as you have invested a lot time and effort to reach this point.

I know I’ve done this before, and it doesn’t feel great. I know teammates of mine have done this before, and it left them feeling apprehensive about what others might think. Each situation required others to step in and pull us out of our holes, which wasn’t easy because we had dug so deep, but eventually, we climbed out.

Everything up to this point has detailed what and where things can go wrong, but I haven’t given you anything constructive to work on. To change that, I’ll close out this post with my thoughts on preventing yourself from reaching the point of no return as you strive to attain your perfect solution.

Personally, I think you should do the following:

  1. Adjust your route to your desired solution as needed - The first step is to introduce flexibility into your solutions. You should still strive to reach your desired outcome, but you should be willing to adjust the route you take. Being flexible will help you tackle the minor setbacks that always arise when working on a feature or bug.
  2. Seek guidance or assistance if you think you are losing your way - It is a good idea to seek help from others if you feel that you’re veering off course. Ideally, you would turn to a colleague that understands what you are working on, however as you likely know already, sometimes the mere act of explaining your thought process to someone else can help you unlock new ideas or clarify your existing thoughts. The main point here is to stop and think before moving forward. Leaning on your teammates for assistance, even if they are only acting as a rubber duck, can help decrease the time it takes to correct your path.
  3. Alter your solution as more significant problems arise - As larger issues occur while you work towards your preferred outcome, you will need to consider if delivering it is possible, this includes whether it literally cannot be done, cannot be done within the required timeframe or requires knowledge that you do not possess. If you have run into a critical flaw in your solution that prevents it from ever working, you’ll definitely need to change course; however, this assumes you realise the severity of the problem, which isn’t always obvious…
  4. Do not wait too long to repeat the previous steps - If you can incorporate the steps above into your work, then you should be on a good path to reliably complete any piece of work assigned to you. The last helpful point I could think of is ensuring that you find the right balance of perseverance and adjustability. You want to try and achieve your perfect solution, but also be aware when you’re going in the wrong direction. I’d say it’s best to start on the end of persevering and then dial it down as you get more of a feel for your personal working style. Starting on the opposite end of the scale, where you’re super adjustable, will likely prevent you from achieving anything because you won’t know when to commit to an idea, so I’d avoid this if I was you.

At the end of the day, it’s about finding out what best works for you. If you’re successfully completing your work to a high quality and on time, then you’re on the right track.

Everything I have written down here comes from my own thoughts and observations from interacting with my colleagues and reflecting on my own working style. The points listed out earlier are the results of my thinking.

What I cannot do, is guarantee that they fit for you, only you’ll know that. Ideally, you’ll reflect on how you work to figure this out yourself and use what I’ve written here as guidance. Without self-reflection, self-improvement is much harder to achieve.

Written by Dan Newton
Twitter
LinkedIn
GitHub