There is a reason why perfectionism is seen both as a positive and a negative personality trait. Human beings have imperfect knowledge and wisdom, which means that today's perfection is tomorrow's disaster. Perfection lives across eternity. Something cannot be perfect if it isn't perfect forever. Despite this unsolvable, problem, many have tried. Most failures go unnoticed but many are plastered across newspapers and history books.
Everyone knows perfection is unattainable, but it has a tempting allure that keeps sucking people in. People who should know better.
I remember my first job like it was yesterday. I remember the things I struggled with. I even remember what I had for lunch. Something that really stuck with me though is how the company I worked for created a motto or tag line for the IT department.
"Getting it right the first time."
There was an idea that the quality of the work delivered was producing problems for the business. In order to change that, all that was needed was some encouragement. We just had to get it right the first time! At this particular place (but many at the time to be fair) there was no quality assurance, no unit or integration testing and no automated deployments. In retrospect, it's a miracle that we got things to work eventually, but the first time was never an option.
As my career progressed with one unmitigated disaster to the next, I reached a place where things were working better than anywhere I had seen before. It wasn't a miracle and it was far from perfect. Disasters were a near daily occurrence because of the risk appetite of that business. However there was a key differentiator that made things work way better.
The trick wasn't to eliminate risk entirely by running a gauntlet of quality gates. On the contrary, the solution was rather simple. If you fixed a bug, it would be tested by a quality assurance person and then it would promptly be rolled out to production.
The releases took a few minutes and the rollback was equally fast. This kept business interruption to a minimum. What's even more surprising is that even though there were many more rollbacks than in teams with longer development cycles, the ratio of releases to rollbacks were much lower in teams with more stringent process based delivery. This approach does away with the obsession of making a release or feature perfect and instead focuses on speed. This is where the infamous and somewhat misguided idea of move fast and break things came from. Moving fast was the right thing to do, but being cavalier about breaking things not so much.
As I moved on from that position I was struck by how teams with much stricter quality gates including in depth code reviews, enforced architecture rules, multiple complete system QA tests and automated tests were performing poorly. All these additional steps were there exactly to improve performance. So why doesn't it?
The reason is this: perfection produces a dilemma.
On the one hand, if your software has deficiencies, then to attain perfection you have to change it.
On the other hand, if you change your software to address deficiencies and attain perfection, things will break.
More often than not, the attempt to address the dilemma is to try and introduce quality gates in order to prevent breakage.The thinking goes that with enough of a process breakage will end and we can inch slowly toward perfection. Every time something goes wrong, another process is introduced to prevent it from happening again. Trying to solve the dilemma from this angle always has the same effect: stratified software. Far from producing perfect software, deficiencies remain for extended periods of time. Lower priority deficiencies are buried like fossils in a code base that cannot change with the adequate pace to address them. Features accumulate like strata in the geological record. Architecture becomes archeology, because understanding the "Functional epoch" is more important than understanding the future, because the accumulation of change is so slow that it's hardly noticeable.
The other angle of attack is to accept that the old software is deficient, to discard it and to start anew. In order to ensure perfection, the new software must be deliberated, theorized, projected and planned to perfection. It was the decisions in the legacy software that ruined the perfection after all. This just replaces one series of strata with a brand new series, because just like geology, the same process will produce the same result.
When I present the dilemma to others they can understand it, but you can see there is a part of them that is desperately trying to wrestle the horns away in the back of their heads. The dilemma only exists when there is a conscious or subconscious belief in perfection. Once the belief in perfection is shattered, there is a response that is just as bad: Despair.
On this view software will always be broken and we need to get everyone involved to understand the broken nature of software. This presents itself in many creative ways but ultimately it results in a break down of trust with users and low morale in the software team. It is also punctuated by attempts to try and claw back to perfection, or at least try to prevent the worst from happening. The five stages of grief might be informative here. In the end teams are building software for users that don't want it.
The truth about software is that being in flux is the point and perfection is unattainable. Requirements, technology, runtimes, frameworks, organisational structures, economic environments and people all change constantly. This is a strength of software. It can change. Removing barriers to change is how we make better software. Instead of laying down sediments, we could take instruction from Bruce Lee.
“Be like water making its way through cracks. Do not be assertive, but adjust to the object, and you shall find a way around or through it. If nothing within you stays rigid, outward things will disclose themselves. Empty your mind, be formless. Shapeless, like water. If you put water into a cup, it becomes the cup. You put water into a bottle and it becomes the bottle. You put it in a teapot, it becomes the teapot. Now, water can flow or it can crash. Be water, my friend.” ― Bruce Lee
Having the ability to react to the environment the software finds itself in makes for great software. Great software is not always consistent, uniform or without flaws. By reacting to the environment we react to the most pressing aspects of that environment. We don't need a five year target architecture roadmap, stringent code review requirements, endless quality gates, plans and meetings.
As with many things in life, the solutions are simple but require hard work. People need to step out of their comfort zones, abandon cherished beliefs, fight their own impulses and innovate. Interpersonal skills become much more important in this journey.