Practical .NET

Why I Hate Best Practices

Best practices and principles aren't rules. They're guides to the judgement of the programmer. Sometimes we forget that.

I was at a client's site, and the team I was part of was reviewing some code I'd written. One of the programmers at the review pointed to a piece of my code and commented, "You shouldn't do that." When I asked why I shouldn't do that, the response was, "It violates the X best practice."

I didn't find that answer satisfactory. I had written the code to solve or avoid some sort of problem. Therefore, the correct answer to my question wasn't, "It violates the X best practice." The correct answer would have been either, "It will lead to this unfortunate result or to this problem down the line, which is worse than the problem you're solving," or, "Your code doesn't solve the problem. All it does is move the problem around -- and not in a good way." If the developer had wanted, he could've added, "That's the reason we have the X best practice."

At some point, for this programmer, "best practices" or "principles," had stopped being "best practices" or "principles." Instead, they had become rules to be rigidly applied in every situation.

The Real Definition of a Best Practice
The definition of a best practice (from Wikipedia) is: "a method or technique that has consistently shown results superior to those achieved with other means." The term "consistently" is a powerful one, but it isn't the same thing as "always."

Principles and best practices allow us to understand particular classes of problems and then to avoid those problems. The reason they're called "principles" or "best practices" (and not "rules") is precisely because the people who invented these practices and principles did not want them blindly applied: They recognized that the problems we're solving are too complicated to be handled by applying rules.

This "world without rules" is the one we, as developers, live in. Back in the late 1980s every article I read on the future of programming heralded the coming of "Software Engineering" when software development would become a discipline instead of a craft. In this new age we would feed the requirements into one end of a process and get working applications out the other end. I won't belabor the alimentary nature of that metaphor (and its output) but I will point out that, 30 years later, we're still practicing a craft that hasn't yet evolved into a discipline (and, by the way, when real engineers build a bridge, they may carefully calculate their tolerances but they always add in some additional "buffer").

I've also seen the damage that rigidly applying a best practice can create. There was a time in my consulting career when the most common problem my clients had was that their reports took too long to run. Invariably, it turned out that my client was running their reports against a database in third normal form and their report, as a result, had to join together half a dozen or more tables.

If only a transaction's worth of rows had been involved, this wouldn't have been a problem. But with a report processing hundreds or thousands of rows, the database engine was overwhelmed. Whoever had taken the reporting database to third normal form hadn't understood the problem third normal form solves: Third normal form drastically simplifies updates. In a reporting database where updates consist of inserting rows every night, simplifying updates isn't an issue. In a reporting database, first normal form is sufficient.

Justifying Best Practices
I don't think I'm ignorant about why developers do advocate for best practices. I do realize that just because, right now, we can't imagine a problem doesn't mean there won't be a problem. Developers who want to use some principle or best practice often stress that our inability to imagine a problem might just be telling us about our ability to imagine the future and nothing about the actual likelihood of having a problem. They want to apply the best practice to protect us from problems we haven't imagined.

And I do sympathize with that view (even if I don't agree with it). I came into this craft at the tail end of the structured programming wars when the "goto" statement was banished as a poor practice. The claim of the programmers who wanted to continue to use the "goto" statement was that some problems were better solved with the statement than without it.

One very intelligent columnist (whose name I have, sadly, forgotten) conceded that there might be a class of problems where using the "goto" statement was a better choice than the best practice of structured programming. However, that columnist went on to say the burden was on the programmer who wanted to use the "goto" statement to provide a demonstration that structured programming would not provide as good a solution as the "goto" solution.

I can see that those advocating for a best practice might feel they're in the same position. From that point of view, it's my responsibility to demonstrate that the best solution in this case doesn't involve the best practice. And, quite frankly, I'm willing to do that.

But I think that those who, back in the day, advocated for structured programming were in a better position than those who, currently, advocate for the blind application of "best" practices. The advocates for structured programming had mathematical proofs that every programming problem could be solved with less complexity using three or four structures. Even among the programming practices and principles I do hold dear, I don't know of even one that rises to that level of proof.

For example, as fond as I am of the Single Responsibility Principle, I wouldn't make it a rule because I don't think we have a very good definition of what a "single responsibility" is (certainly not a mathematical one). While I value clarity in my code more than efficiency, I have rewritten some "really obvious code" into more obscure code to fix a performance problem. And I'm not sorry about that, either, because (to quote Adam Turner) I believe that "Performance has no competition." But I also believe that "Fast enough is good enough" and I won't optimize some obvious code into obscurity unless there are actual complaints about performance.

So, for me, the responsibility for applying a principle or practice still lies on the shoulder of the person advocating for it. I know the problem I'm solving. Before someone can get me to alter my code, they have to know the problem their change will solve or present. I think that's only fair. Moreover, in the absence of that explanation, simply invoking a best practice isn't going to convince me to change my code.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at

comments powered by Disqus


  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

  • .NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

    Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.

  • Data Anomaly Detection Using a Neural Autoencoder with C#

    Dr. James McCaffrey of Microsoft Research tackles the process of examining a set of source data to find data items that are different in some way from the majority of the source items.

  • What's New for Python, Java in Visual Studio Code

    Microsoft announced March 2024 updates to its Python and Java extensions for Visual Studio Code, the open source-based, cross-platform code editor that has repeatedly been named the No. 1 tool in major development surveys.

Subscribe on YouTube