The perfect is the enemy of the good (and the done)

Dear new developer,

When you are facing a problem, it can be very tempting to try to solve it perfectly. Handle all the possible edge cases, make it extensible, have it be configurable without code changes.

As with everything in life, there’s an opportunity cost to this perfection. If you’re spending days perfecting a single page of a webapp, for example, you won’t be able to move on to the next feature.

There are times for perfectionism, without a doubt. When data could be lost or security could be compromised, you want to move slowly and carefully.

For the rest of the time, good and done is better than perfect and undone.

Of course, the definition of ‘good’ is the crux of the above statement. Unfortunately, this is a judgement call, depending on context, team and risk. One thing that is non-negotiable is that the code meets the requirements. If it doesn’t work, then nothing else matters.

Some things to think about when you are considering what ‘good’ is:

  • How often will this be used? Once a second? Once a year? Once?
    • The more often code is used, the more it should be polished.
    • Note that usage often changes over time, so it’s worth keeping an eye on this and spend some time cleaning up code if it moves from the once a year category to the once a week category.
  • Is this a relatively static part of the system, or is it in flux?
    • If you’re touching this once and don’t expect to touch it again for a while, taking some extra time makes sense. Niggling bugs may live for years.
    • On the other hand, if this area of the codebase is churning, polish could be wasted because the code may be trashed.
  • What are the risk factors if this fails? Will someone be killed? Will money be lost? Will someone be inconvenienced?
    • Obviously, the higher the risk, the more care you should take.
  • What is the next thing on the list?
    • If you have other high priority issues, you may want to avoid polish.
  • What is the team quality ethic?
    • You should meet and improve that standard. For example, in the context of testing: if no one writes tests, set things up to write tests. If everyone writes unit tests, think about integration tests. If everyone writes integration tests, think about performance regression tests.
    • This is a great topic of conversation at an interview or team meeting so that everyone can be on the same page.
  • How permanent is this code?
    • The more permanent the code, the more care should be taken.
    • Some code lives on servers and is easy to change. Other code is shipped to mobile apps and is harder to change. Yet more is distributed to IoT devices and really hard to modify (when is the last time you updated your router’s firmware? I thought so.). Some is burned to read only memory and can’t be changed short of great expense.

One question that I’d avoid asking is “how will I feel about this code in 12 months”. Because I know the answer–you’ll cringe. At least, in all my discussions of running code, I’ve never met someone who revisited old code and didn’t find at least one thing to improve.

Two examples, rating the above factors on a scale of 1-5 (where 1 indicates you should just get it done, and 5 indicates you should get as close to perfection as possible).

  • Your website portfolio:
    • Usage: 3. Used maybe once a year or two (if you are an employee) or maybe every month (if a contractor), when someone is checking you out.
    • Static or churning: 4-5. relatively static. You probably build out an example app once.
    • Risk factor: 3. You’re looking for a job, and your portfolio is a powerful signal, but not the only one.
    • Next thing on the list: ?
    • Team ethic: N/A
    • Permanence: 1. This is a website, so you can ship new code whenever you have time.
  • Billing software on your large public site:
    • Usage: 5. Used many times a day.
    • Static or churning?: 4-5. Should be relatively static as payment processing doesn’t change that often.
    • Risk factor: 4-5. Billing mistakes are expensive.
    • Next thing on the list: ? Depends on the company.
    • Team ethic: ?
    • Permanence: 2. You have the code on the server, but you have a lot of history and state to maintain.

When you are working on code and struggling to get to ‘done’, I encourage you to consider the above questions to guide your decision. Finally, don’t forget that (most) code can be revisited. If something is good and done now, ship it. You can typically improve it next week or next year if the code needs it.