With all the static code analysis tools and books and blog posts on coding conventions there seems to be a new sentiment that you can get good code out of arbitrarily bad developers by just imposing enough rules upon them. That might seem like an IT project leader's dream. Just hire the cheapest team possible, devise some arbitrary coding guidelines and then watch the project succeed. But reality paints a different picture: Bad coders will find ways around your rules and good coders will roll their eyes at their arbitrariness.

Nothing replaces discipline. Nothing replaces a good sense of quality.

When you try to use static analysis to "enforce quality" you are bound to be disappointed. Good coders adhere to most of the rules anyway and will sometimes be hindered when an overly strict rule marks a perfectly sound piece of code as "bad". And bad coders will find many ways to circumvent detection. Be it by just scattering "//Checkstyle OFF" in the codebase or by altering their code in a way that makes it pass the checks but actually turns out to be even worse.

Let's look at a simple example of what will happen if you want to forbid inner blocks in Java. The following code uses an inner block to hide the variable "someNumber" from the rest of the method:

public void foo() {
  doSomething();
  {

    int someNumber = 1;
    calculations(someNumber);
  }
  doSomeMoreStuff();
}

The obvious fix would be to extract the block into a new method. But what a bad coder will actually do to get around checkstyle is the following:

public void foo() {
  doSomething();
  if (true) {

    int someNumber = 1;
    calculations(someNumber);
  }
  doSomeMoreStuff();
}

Of course you could go on and forbid always true conditions, but we can get around that, too:

public void foo() {
  doSomething();
  boolean dummy = 1 == 1;
  if (dummy) {

    int someNumber = 1;
    calculations(someNumber);
  }
  doSomeMoreStuff();
}

This already requires some more sophisticated analysis and many tools will not object to it. The bitter truth is: You cannot change bad developers. And no amount of static analysis will ever help you in such pathological cases.

What static analysis is actually good for is to gently tell a good developer that there seems to be some need for refactoring. If that person is at all concerned about code quality he will be happy for such helpful pointers. It can also be used to remind people of best practice tidbits like "don't use new Integer(), use Integer.valueOf()".

But even conventions that everyone in the company agrees upon don't necessarily improve quality. Sometimes such a convention is imposed to cover up for deeper problems in the code. I stumbled upon such a convention in a recent project. It was a naming scheme and went like this:
  • prefix static fields with "cls"
  • prefix fields with "obj"
  • prefix local variables with "var"
  • prefix method arguments with "arg"

This has some very annoying effects. First of all, some tools rely on properties and their getters/setters being named the same. But you definitely do not want to call a method "getObjName()". So that usual contract is broken. Secondly, auto completion gets a lot less useful. If I want to search for something called "name", I first have to type the correct prefix. For that I need to already know whether "name" is a local, parameter or field in the current context. And last but not least it can warp mathematical algorithms beyond recognition. Imagine Gauss' computus algorithm with "var" in front of each variable.
When I asked why that would be at all helpful, the team leader told me: "It helps you tell quickly where a variable comes from". I suggested that all modern editors have syntax coloring for exactly this purpose and that color can actually be parsed more quickly by our brain than any variable prefix. "But there is no syntax coloring on the command line and Eclipse does not have different colors for local variables and parameters." was the final verdict on that subject.

That whole discussion got me thinking and I concluded that the root cause was "needing help at discerning different kinds of variables" in the first place. I looked at the code that the team leader had to read through at a regular basis: It had many classes with a dozen fields and more, classes which were a couple thousand lines long and which had methods spanning multiple screens. No wonder he needed help in understanding these. But adding those variable prefixes was just a crutch. It did not solve the root cause: Poor code quality.

In a well written class there are only very few fields. Methods are often no longer than a handful of lines. Additionally, methods have only very few parameters which makes naming those parameters easier. Local variables should be far and in between and should be used to give a meaningful name to an important intermediate result. Instead, most methods of a class should use many or even all fields of that class. If you follow these guidelines you will end up with many small classes that focus on doing one thing properly. More on how to achieve these standards can be found in Robert C. Martin's Book "Clean Code".

In the past weeks I have written many such focused classes and broke up some of the big old ones, too. In that process I also refrained from using variable prefixes. No one misses them. So in the future we'll be able to remove the corresponding checkstyle rules and have one less annoyance to think about.

Nothing replaces discipline.