Static Analysis tools > Experience
When developers choose to enforce Static Analysis tools (i.e. JTest or PMD) they might have the best intentions at heart, but are actually making the code worse in the long run. The value of the programmer’s experience and expertise on the code is not considered. Static analysis tools are automated programs that run a set of rules against source code to produce metrics, and give advice on best practices. So why does using these tools lead to bad code?
The HeartacheYou’re trying to finish up some down-to-the-wire coding to get it over to your Testers, and your deadline is approaching. You have this one last class to change and it is a legacy class. This class was written before the static analysis tools were forced to be run on the code base. You go in to make a simple change like adding a null pointer check. You now execute the static analysis tool on the code and you have 30 violations — from incorrect naming of fields to Cyclomatic Complexity greater than the threshold. You have 2 options here: A) You take the time to fix all the violations, and leave the code better than you got it or B) You take the lazy / easier solution and try and beat the rules — take the easy way out and work around them. What do you choose?
Reaction to the painDepending on what option you chose, you left the code beautiful, a little bit better, or in shambles and worse than you received it. By choosing option A you decided to be Pragmatic and make the code fix the Cyclomatic Complexity. Now being the pragmatic programmer you are you need to consider unit testing. You take the time to understand the violating method and make the appropriate refactoring. Now you hope the developer before you would have tested this method. A lot of the times this is not the case or if it is the case, did they write a good test? Did they write a test just to pass the code coverage standard? Again you have options, you can either take the time to use TDD or you make the refactoring without the test and hope you don’t break anything. If you chose option B, you decided to hack the code to bypass the rule. By circumventing the system you are making the code worse, harder to understand, and more likely broken. You figured out that by extracting pieces of the Cyclomatic Complexity method into other methods bypasses the rule. This doesn’t truly fix the Cyclomatic Complexity it just hides it from the tool. Again you have to worry about test or not to test. Lets look at another less extreme example, you’re now forced to fix a rule that is complaining because the code uses the ‘!’ operand more than max two times mandated by the rule. You might change the code to “== false” or flip the condition blocks so that it results in true and use the else to catch the false. This does work on a case by case basis. However sometimes flipping the if expression to check for true first makes the code harder to read. By making this change it loses the developers intention. You are probably making the code worse by trying to beat the system or making the rule happy. Is the code still easily understood by making this change? Taking the Dreyfus Model into account will help us determine why a developer would respond in these different ways.
Dreyfus ModelBy using the Dreyfus Model we can rate developers into 5 different categories: Novice, Advanced Beginner, Competent, Proficient, and Expert. Novices are driven by rules and need guidance to complete tasks. While the Experts are passed rules and use their intuition to drive their decisions. Something to note about Experts is they can’t explain why they do the things the way they do. A Novice that is driven by rules will likely fix the problem without hesitation or they could just be lazy and don’t want to push themselves to do the exploratory fix. Now with Experts they will question the rule violation against their code. Experts will not just blindly fix the error if they believe their code is correct / a work of art. This is not their ego talking, but more their experience / intuition / instinct on the subject. Not all developers are made equal, so why do we think code should be? The Expert will likely not be able to verbally prove their reason for wanting the violation to be suppressed — to them, it’s just clearer and better their way. By not trusting their instinct you are degrading them. They are likely going to strike and push back against this rule, toying with the Enforcer. Forcing rules on the Expert is an incorrect way to treat them and their knowledge. Rule violations shouldn’t be blindly enforced but taken on a case by case basis.
Learning ToolI do believe that Static Analysis tools make a great learning tool towards best practices. Novices, Advanced Beginners could get a lot of benefit from seeing what they did incorrectly when they violated a rule, and learning from it as they progress in their career. A lot of time you are doing maintenance on code someone else wrote before the tool was enforced to be run. Now you are held accountable for the fixing the rule when you just came into this class to add a new field. First off this leads to developers to not wanting to make code changes even though they know it is for the best. Also you are now held accountable from someone else’s debt. The original developer might have moved to another team, and hasn’t seen the debt they have incurred. Now the original developer can’t learn from this experience. Hopefully when a rule violation is found against someone else’s code it will be shown to them so they get to see the debt they incur. Developers should be taught to write good code in the first place, but without good mentors that is going to be hard. Especially when the Experts can’t explain why they do the things they do. I don’t think that Static Analysis tools should replace code reviews and agile pair programming. Code reviews should still be done, and require at least another set of eyes on each line of code written. This will help foster the mentorship and help less experienced programmers with a more experienced developer.
ConclusionUse Static Analysis tools as a guidelines not a mandate. Use these tools as training guides for younger developers, and for the advice they are built to give. Enforce rules on a case by case basis not at an overall perspective. By enforcing these tools it causes developers to rebel, make the code worse, and not to want to make code changes because they are going to be responsible for fixing the rule that they might have good reason to disagree with — passionately. Please let us know how have you dealt with these tools or situations in the past. What pain have you felt from these tools? References: Dreyfus model: Developing Expertise: Herding Racehorses, Racing Sheep by Dave Thomas
Posted in Best Practices