In Good to Great, Jim Collins states that “good is the enemy of great.” In Working Effectively with Legacy Code, Michael Feathers states that “we can’t let ‘best’ be the enemy of ‘better’”.
On the surface these seem contradictory, but I would argue that they are, in fact, complementary. I have been very much guilty at times of getting “analysis paralysis”, being overly concerned with the “right answer” or the “right way”. In that case, where you have nothing, doing something is better than doing nothing. At the very least, doing something, even if it’s wrong, gives you feedback that it’s wrong and you can move on. The trick is to do something that is low risk. The smaller your something is, the faster you can get feedback and adjust.
This goes with the “release early” philosophy of agile. The other part of that philosophy is “and iterate” which is important as well. Getting something done allows you to take it and improve it. Having something concrete via quick prototyping or tracer bullets and iterating can get you there faster than waiting for the “right way” to become apparent. If we always think “I don’t have time to make it perfect so I won’t do anything” we will never do anything. “Best” becomes the enemy of “better.” Martin Fowler said as much:
When you actually sit down to write some code, you learn things that you didn’t get from thinking about them in modeling terms. There is a feedback process there that you can only really get at from executing some things and seeing what works.
Once we get something good enough, the problem then becomes the attitude that “I don’t think it’s worth the effort to improve it, it’s good enough.” And here is where “good is the enemy of great.” The problem becomes when everything is humming along “well enough” that we become complacent. That is until something shakes things up. Like when the weight of defects reported become overwhelming because the code was not kept clean and non-legacy (no automated tests). Or when an economic downturn hits and you realize that you didn’t take the opportunity during the “good years” to fine tune things or expand and improve and are now faced with tough decisions.
We need to be constantly improving (in code, in business and life), not settling for good, striving for great, but not so worried about best that we don’t pursue better.