Design Philosophy And Coding Style

Caution, Rant Alert!

In my career, I have been some kind of leader on about a dozen new application projects. It is interesting to me that the only time I have ever heard about “design philosophy” or “coding style” is when some new developer comes on a project and gets his butt handed to him in a code review. Specifically, what I hear is a defensive posture which sounds like an excuse for code that is not a good fit for purpose or consistent with the surrounding application.

In a prior post HelpingTheTeam I talk about some new developer problems. This is another, perhaps less common issue.

Here is a list of bad coding practices that I have heard defended as “design philosophy” or “coding style” and why they are neither philosophy or style:

1) Not following the established architecture pattern of the application.

Design philosophy is what amounts to a set of guiding principles covering some aspect of a design process. Since the design process is complete, and it resulted in the established architecture pattern, what this amounts to is the developer saying “My personal design philosophy nullifies any prior design exercise performed by the team.” It is never, ever, EVER, a good thing when a developer goes off pattern, and then defends it as a difference in philosophy or style.

2) Using any strategy that increases code complexity unnecessarily.

Coding style that results in code that has more components, more logic, or more layers or even more lines is questionable. Sometimes even too many comments makes the code less readable or maintainable. Anything that obscures the essential logic, or the ability of developers to discern the purpose of a component is not helpful. I worked with a developer once that wrote (I kid you not) a 700 line method with 8 levels of looping because he didn’t understand recursion. His response when I reviewed his code, was that my critique was a “matter of style”. He was surprised when I replaced his monstrocity with a 35 line function – even more surprising was that he understood it better. This isn’t philosophy or style – it is ignorance. It took him two weeks to get his method even to work partially. I had mine working in an afternoon.

3) Cut and Paste – Having multiple instances of the same logic.

It is very easy to make things work, by cutting and pasting working code from one place to another. Much harder it is for those who follow to remember to change the logic in all of the right places. Even the originator after making mistakes that propagated to all of the copies starts to slow down when they discover defects in the logic. If you are using automated unit tests, it gets even crazier – now I have to cover the same logic with tests each time I copy it. The instant pain of having to test copy paste code is maybe the best reason I have for insisting on unit test coverage. This is neither style nor philosophy it is sloppiness and laziness.

4) Writing logic that is difficult or impossible to write unit tests around.

Sometimes a language or paradigm provides a way to implement something that is very elegant, or efficient – but does not provide a way to easily install unit tests to cover it. If you are using an automated unit test framework and TDD or at least test infected development – it is better to use more direct or obvious (and testable) coding patterns.

5) Using non-semantic names for classes, methods, properties, etc.

A long time ago, we used short, abbreviated variable names because computers had limited memory, storage, and space – these abbreviations were necessary to get work done. My first job required me to write MS Basic, which only allowed two character (all caps) variable names. Such were the limitations of the time. Now languages and computers have fewer limitations, so they allow programs to be expressed more semantically. Yet, I still see programmers using non-semantic variable names like x and i. This naming strategy requires all who follow to infer semantics on the code. The variable is not what you call it, it IS how you use it.

6) Leaving old code hanging commented out for posterity.

Back in the days before useful source control systems, when checking in your changes was really a formality that you did before you migrated to production or a superior test environment, so that you could rebuild THE MIGRATED VERSION – we had different practices. It used to be preferred to leave older logic in line in the code base, so that we could “remember” the logic we replaced to support the new requirements. Given modern tools and practices, where we check in our changes and build and migrate very frequently, there is no reason for this. What is worse, after a while, it clutters up the code base. Instead of making things easier to understand, it takes up space and makes less actual code fit on the screen. It may remind us of an algorithm that was fixed because it was defective. It may remind is of a structure that is no longer valid. Just cut it out. Use your source control tool to remember what was there yesterday, last week, or last year.

Why philosophy and style replies to code review critique are ALWAYS bullshit:

1) The code review IS NOT when we make decisions about which design patterns to follow, or how to assemble code. After you have gone off the reservation is not the time to try to change the borders of the reservation. If you had been more collaborative while designing the thing you built and understood the surrounding code base more clearly, you could have gotten feedback before you invested 2 days in building the wrong thing.

2) The code review IS NOT when we make decisions about coding standards and naming conventions. Those decisions should be made pretty early, because they grow progressively more expensive to change as the code base grows in size. That said, there are often times when we adopt one standard, find that it is insufficient then adopt another.

3) The code review IS NOT when we should be defensive. Using the words philosophy or style to support your approach is completely defensive. If your code were superior, you would be defending it pragmatically, using its merits (efficient, elegant, pragmatic, maintainable, easy to understand) instead. The code review is a time when we should be open minded so that we can learn from others. It may be our best tool to raise our skill level and explore alternative strategies. Sure it would help if we did this before the code review, but a code review is a way to enforce this behavior. If we are defensive, it should cause us to question why we were not more collaborative while we were coding. Do we really believe that our approach is superior? Or are we just trying to avoid re-work. Using style or philosophy are really just a different way of saying “this is what I like”.

I will leave you with these quotes about coding style:

 "Write your code as if the person who will be maintaining it is a violent psychopath who knows where you live." - Martin Golding

 "The trouble with programmers is that you don't know what they are doing until it's too late" - Seymour Cray

Before you respond to critique referencing either a style or philosophy argument, think hard about the real pragmatic benefit of your approach to solution, and if you can’t come up with reasons why yours is better than the suggested approach, keep your mouth shut, listen and learn from others.

No Comments

Post a Comment