You Cannot Fix Bad Coder Thinking
There are certain concepts in software development where you either “get it” or you do not, and for the most part they are concepts that good developers just intuitively understand. Some of these things, a less experienced developer may not have the knowledge to understand them, but once provided the knowledge they understand the concepts without any further explanation.
A great example of this is “why do we separate code into smaller functions and modules instead of throwing it all into one big function or module?” There are plenty of others like this, and many of them simply fall into what I would call “programmer hygiene”. There are some adults that do not understand that you need to brush your teeth, and no amount of explanation, begging, pleading, or nagging will get them to start. Likewise, I cannot force a grown adult software developer to develop a sense of good judgement.
At best, what I can do is create a giant set of checklist rules telling developers how to do things, then insist that the checklist be followed to the letter. The end result is a group of “Checkpoint Charlies” that do not/cannot/will not think on their own. A sign of a great developer is that they understand that the “rules” are really “guidelines” and in certain circumstances, they can and should be discarded. The checklist driven development approach does not allow for this flexibility and can crank out some truly horrific software that looks like solid code.
At the end of the day, the goal is not “make sure that all functions fit on one screen” or whatever your checklist says, the goal is “make great software.” The checklist driven development approach confuses the symptoms of well-written code with the cause of well-written code. To make the matter worse, checklist driven development actively disguises bad developers and bad code, because now the problems masquerade as good developers and good code.
Do not get me wrong: there is value in documenting and following “best practices”, whatever you have determined they are for your project, industry, toolset, etc. A big part of my daily job is doing just this. Checklists most definitely have their place as well (especially on the operations side of things!). But the value is not in blindly adhering to “best practices” for the sake of doing so, but to use them as a tool to educate and fill in the knowledge gaps of the team.
It becomes much easier to evaluate if a developer is “good, but lacking knowledge” or if they are simply a bad developer through the coaching process. When I have tried to coach bad developers into good behavior, they merely fixed the problems with the specific code that I called out as an example and leave the other two dozen instances of the same mistake as-is. They were unable to extrapolate from the knowledge provided, and simply acted on the checklist that they were provided with, in this case the examples of bad code that I reviewed with them.
Some shops just have to have a pile of “warm bodies” to throw at projects, and I can see why those places might keep bad developers around. But if you have the choice, and encounter someone who cannot translate new knowledge into better code it is time to seriously consider letting them go. You simply cannot make people with bad judgement into good developers.