I used to be very confident in my abilities as a software developer.
I used to be able to walk up to a group of software developers and tell them exactly what they were doing wrong and exactly what was the “right” way to do things.
I used to be sure of this myself.
It wasn’t even that long ago. Heck, when I look at the blog posts I wrote 3 years ago I have to slap myself upside my head in realization of just how stupid I was.
Not only was my writing bad, but some of my thoughts seem so immature and uneducated that it feels like a completely different person wrote them.
And I wrote those posts back when I knew it all.
The more I learn, the less I know
Lately I’ve been running into situations more and more often where I don’t have a good answer for problems.
I’ve found myself much more often giving 3 pieces of advice attached with pros and cons rather than giving a single absolute—like I would have done perhaps 3 years ago.
I’ve been finding as I have been learning more and more (the past 3 years have been an accelerated pace of growth for me,) that I am becoming less and less sure of what I know and more and more convinced that there is no such thing as a set of best practices.
I’ve even spent some time postulating on whether or not commonly held beliefs of best practices would be thrown completely out the window given a significant enough motivation to succeed.
My point is that the more doors I open, the more aware I become of the multitude of doors that exist.
It is not just the realization of what I don’t know, but also the realization of weakness of the foundation I am already standing on.
Taking it out of the meta-physical
Let’s drop down out of the philosophical discussion for a bit and talk about a real example.
Perhaps the biggest quandary I struggle with is whether or not to unit test or practice TDD and its variants.
The 3 years ago know-it-all version of me would tell you emphatically “yes, it is a best practice and you should definitely do it all the time.”
The more pragmatic version of me today says, in a much more uncertain tone, “perhaps.”
I don’t want to delve into the topic in this post since I am sure I could write volumes on my ponderings in this area, but I’ve come to a conclusion that it makes sense to write unit tests for code that has few or no dependencies and that it does not make sense to do so for other code.
From that I’ve also derived that I should strive to write code that separates algorithms from coordinators.
I still even feel today that my advice is not wholly sound. I am convinced it is a better approach than 100% TDD and units tests, or no TDD and unit tests, but I am not convinced there isn’t a deeper understanding and truth that supersedes my current thoughts on the matter.
As you can imagine this is quite frustrating and unsettling.
Silver bullets and best practices
What I am coming to realize more and more is that there are no silver bullets and more surprisingly there are not even any such things as best practices.
Now I’ve heard the adage of there being no silver bullets so many times that it makes me physically sick when I hear someone say it, because it is so cliché.
But, I’ve had a hard time swallowing the no best practices pill.
I feel like when I abandon this ship then I am sailing on my life raft in the middle of a vast ocean with no sails and no sense of what direction to go.
A corner-stone of my development career has been in the learning, applying and teaching of best practices. If these things don’t exist, have I just been pedaling snake oil and drinking it myself?
No.
Best practices are simply concrete applications of abstract principles in software development that we cannot directly grasp or see clearly enough to absolutely identify.
Breaking this down a bit, what I am saying is that best practices are not the things themselves to seek, but through the pursuit of best practices we can arrive at a better understanding of the principles that actually are unchanging and absolute.
Best practices are optimal strategies for dealing with the problems of software development based on a particular context. That context is primarily defined by:
- Language and technology choice
- Meta-game (what other software developers and perceived best practices are generally in place and how software development is viewed and understood at a given time.)
- Individual skill and growth (what keeps me straight might slow you down; depends on where you are in your journey.)
There is a gentle balance between process and pragmatism.
When you decide to make your cuts without the cutting guide, it can make you go faster, but only if you know exactly what you are doing.
Where I am now
Every time I open my mouth I feel like I am spewing a bunch of bull crap.
I don’t trust half of what I say, because I know so much of it is wrong.
Yet I have perhaps 10 times more knowledge and quite a bit more experience in regards to software development than I did just 3 years ago.
So what gives?
Overall, I think I am giving better advice based on more practical experience and knowledge, it is just that I am far more aware of my own short-comings and how stupid I am even today.
I have the curse and blessing of knowing that only half of what I am saying has any merit and the other half is utter crap.
Much of this stems from the realization that there are no absolute right ways to do things and best answers for many of the problems of software development.
I used to be under the impression that someone out there had the answer to the question of what is the right way to develop software.
I used to think that I was picking up bit of knowledge, clues, that were unraveling the mystery of software development. That someday I would have all the pieces of understanding and tell others exactly how they should be developing software.
What I found instead was that not only does nobody know the “right” way to develop software, but that it is perhaps an unknowable truth.
The best we can do is try to learn from obvious mistakes we have made before, start with a process that has had some level of success, and modify what we do based on our observations.
We can’t even accurately measure anything about software development and to think we can is just foolishness.
From story points, to velocity, to lines of code per defect and so on and so forth, all of those things are not only impossible to accurately measure, but they don’t really tell us if we are doing better or not.
So, what is my point?
My point is simple.
I have learned that not only do I not have all the answers, but I never will.
What I have learned is always subject for debate and is very rarely absolute, so I should have strong convictions, but hold onto them loosely.
And most importantly, don’t be deceived into thinking there is a right way to develop software that can be known. You can improve the way you develop software and your software development skills, but it will never be based on an absolute set of rules that come down from some magical process or technology.