Principles Are Timeless Best Practices Are Fads

There is a huge difference between a principle and a best practice.



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.

BusinessmanThere 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. 


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

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.


About the author

John Sonmez


  • cirellolaranjo

    I love this blog because makes me feel I am not an alien. Good to see other people with the same thoughts.

  • SutoCom
  • Pingback: Extreme Programming is a cultural thing | tamasrev()

  • Pingback: Bad Advice: “Stop Working So Hard” | Making the Complex Simple()

  • Pingback: What is the difference between a principle and a best practice? | Question and Answer()

  • Pingback: Bad Advice: “Stop Working So Hard” - Simple Programmer()

  • Pingback: Principles Are Timeless Best Practices Are Fads – by John Sonmez()

  • Pingback: 4 Mistakes I Made When I Started My Software Development Career()

  • Pingback: 5 Điều tôi ước gì được biết khi mới bắt đầu nghề phát triển phần mềm | VinaCode()

  • Pingback: [Dev Rule] 11 Rules All Programmers Should Live By | sudo man()

  • Garri Hovhannisyan

    It’s not the best practice that is effective, it is the principle behind the best practice => short and genius.

    • jsonmez


  • Scott Nimrod

    I find myself a disciple of ﻿Robert Martin’s﻿﻿ teachings. Specifically, I am in love with his
    recommendations of architectural design. He has given several talks on Clean Architecture.

    Software doesn’t need architects to design it. It needs architects to review it.

    What I am not a disciple of are people who continuously try to pretend that they know exactly how a system is going to work based on limited requirements handed down from the client. These people love to draw on whiteboards and software applications that provide UML editors. These people continue to believe that they know everything about a system and will attempt to convince you
    to implement their physic readings. They believe that if an object exists in the business world than an entity is required to represent it in software.

    Unfortunately, failed projects have proven that as much as we try to anticipate how a system is going to work, we will always make discoveries and have to adapt to them when we actually attempt to implement the visions handed down from these divine architects.

    Software is not about architectural design. It is about isolating thoroughly tested logic that’s
    generated from unit tests, that when refactored into logical components, will expose an architecture that conveys the user-stories that created it. Thus, an authentic software architect recognizes software as being “soft” only when they pragmatically defer architectural decisions for a later time up-until they have reached a point of an authenticated impediment. It is at that time within the SDLC that a developer / architect can make a more informative decision based on additional information that has become available that was just wasn’t prior. Thus, it is really deferring decisions all the way to the end that results in software being “soft” and the combination of isolated stories with ssociated unit tests that removes unnecessary dependencies and enhances flexibility.

    Story Driven Architecture

    * Composing an architecture as a collection of user-stories

    * Each user-story is a self-contained module and can only subscribe to messages or publish messages without having any knowledge of the outside world (i.e. client/server).

    * Each user story is tested in complete isolation of other user-stories and again are agnostic to any client or server dependencies via a message-oriented architecture.

    * Start off creating a library / module for each user story

    * This methodology supports Single Responsibility Principle (SRP)

    * Definition of SRP: Keep code together that tends to change together and pull code apart that tends to change for different Reasons.

    * As user-stories get implemented, each library representing a user story is evaluated with other user-stories to determine if any of these libraries can be consolidated into a single library that maintains compliance with SRP.

    Testing user-stories

    * Unit test only view-model commands and nothing more.

    * Inject test dependencies that will dictate test behavior as a light-weight integration test or unit test).

    * RGR (Red, Green, and Refactor) test code into logical components that will eventually distill into a story driven architecture.

  • Pingback: 所有程序员都应该遵守的11条规则 | Andy Luo's Blog()