Best practices are subjective and depend largely on context, while principles are eternal and universal.
After writing The More I Know The Less I Know, I received a few emails talking about how there are absolute best practices that should always be followed in software development.
I had already intended to write about principles, but that confusion made it clear to me that there should be a distinction made between best practices and principles. We don’t want to throw the baby out with the bath water.
Looking at some examples of best practices
First let’s take a look at some software development best practices, then we’ll contrast them to principles to better get an idea of the difference.
One of the most common best practices today in software development is the idea of unit testing. I’ve written about how I have my doubts about blindly following this best practice in the past, but whether or not we should follow it, is not what I am concerned with today.
Unit testing is extremely contextual. What I mean by this, is that almost anyone would agree that there are a certain set of circumstances that makes unit testing have value.
If you work in an environment where the execution of unit tests takes a really long time, or you are developing your software in a waterfall approach where you have a big upfront design and detailed requirements, unit testing starts to lose value rapidly.
But rather than get trapped into the argument of when unit testing loses its value, it is better to address when it has the highest value—we are much more likely to agree there.
Unit testing has the highest value when we are working in agile environments where changes are being introduced into a software system rapidly and refactoring is taking place. It also greatly increases in utility when you are able to execute and write the tests quickly, because that feedback loop makes it much easier to write the tests in a step by step approach, especially when doing TDD.
There are plenty of other best practices that have fallen out of favor, like heavily commenting code and documenting requirements with UML diagrams, but context also greatly played a part in the value of these practices.
When most developers wrote very short variable and method names, comments were really important. Before Agile processes became prevalent, getting detailed requirements upfront was critical.
But, most best practices are good!
Yes, you are right, most best practices do apply pretty broadly and are generally helpful in a large number of different contexts.
For example, it is considered a best practice to use a source control system and it doesn’t seem like there are many situations where this wouldn’t be the case.
So doesn’t that make it a concrete rule or a principle?
No, it is still too specific to be generally applied in all cases and the act of putting your code in source control does nothing to improve the quality of your software or software product.
If you were to blindly follow any best practice and not apply that best practice in a way that brings out the underlying principle, you would be very unlikely to actually receive any benefit.
You see, most best practices are actually derived from universally applicable principles that never change. That is why most best practices are good.
The problem is applying the best practice itself in no way assures the benefit of its underlying principle.
To put it plainly, there is something greater at work that makes it a good idea to check your code into a source control system. It is entirely possible to follow the action, but completely miss the spirit of the action.
More and more today, I see software development teams that are:
- Writing unit tests
- Using continuous integration systems
- Using source control
- Having Scrum meetings
- Pair programming
- Using IoC containers
Yet they are getting little to no benefit from it. Just a bunch more pain and hoops to jump through. The reason is simple…
It’s not the best practice that is effective, it is the principle behind the best practice
Principles are everywhere. They apply in all aspects of our life. You cannot go through the day without being affected by the results of 100s of different principles that have a constant influence on your life, just like the law of gravity does.
Gravity is actually a great way to understand principles. As far as we know, it is a universal force that is always in effect. It is impossible to escape the law of gravity, wherever you go in the universe it affects you.
Principles are like laws of nature except bigger. Principles are more like the laws of reality. Even though you may not be able to describe them fully or understand how they work, they always work.
Take for instance, the law of the harvest. Most people are familiar with this particular principle. It basically goes like this.
You reap what you sow.
How universal is this truth? How can anyone avoid it? How many times have you found yourself subject to this inescapable law about how reality works?
Many software development best practices are actually based on this principle. Think about best practices that have you make efforts to improve the quality of software early on in the process.
TDD or test driven development, is such a best practice. The basis of TDD is to introduce quality into the software development process as early as possible, so that the finished product is better.
If you apply the practice of TDD without understanding this principle, you are just following the motions and you won’t actually gain the benefit of the practice.
If you can’t understand at some level that the point of doing TDD is to sow some good seeds in your software that you will harvest later on, you won’t be writing the right kind of tests.
There is nothing magical about writing tests before writing code, but there is something valuable in purposely investing in upfront quality with the end goal of getting a big yield on that investment in the right season.
By the way, that is why I like Bob Martin’s book Agile Principles, Patterns and Practices in C#; it discusses many principles of software development that are timeless. Books like this one and the book I have mentioned probably 10 times in this blog, How to Win Friends and Influence People, are full of principles.
Also, check it out, you just learned what Agile really is. With principles in mind, now read the Agile manifesto. It was never designed to be a detailed process and set of best practices for developing software, it was always meant to be a recognition of a set of principles that guide software development.
So, just remember the next time you are arguing with someone over a best practice, or consider applying one to a project you are working on, if you don’t understand the underlying principle, no amount of ceremony and procedure will have the smallest amount of benefit.