Myth 3: The source of all bad code is inept developers and stupid people
When you review code is this what you assume? Shame on you. You are probably making assumptions in your code if you are assuming so much already. Bad code can be the result of any number of causes including but not limited to:
- using dated techniques (like boxing when generics are available)
- not following standards (“look how he does the spacing between arguments!” or “did he really just name that variable ‘bln_Hello_Cats’?”)
- hacking around assumptions made in earlier iterations / hacking in features that should be worked into the overall design
- using properties, methods, or techniques in a novel / novice way AKA Hacking / Tinkering (like switching on button.Text between “Hello World” and “Hello World “ //clever use of space character… sigh)
- being redundant
- not following the SOLID principals
The first two issues, while annoying are pretty easy to spot and can be fixed so easily. If your coding team is made up of experienced professionals who are passionate about staying current then these shouldn’t be happening. If you work with a variety of skills, backgrounds, and experience then there will be some of this stuff going on. If you have an opportunity to mentor such a developer who is receptive to constructive criticism don’t be a jerk; help them and the codebase will improve. A little patience can improve the codebase, your work environment, and even your perspective.
I often wonder how much time is actually “saved” by hacking but I wouldn’t call someone an idiot for doing it. I believe the problem to be in the way many of us look at coding. The problem is that coders and sometimes managers of coders think we are paid to write code; When in fact, we are paid to solve problems for our users. Writing code doesn’t solve problems. Rushed developers will use what they think they know and neglect the possibility of what they don’t know. In response to this many development shops have moved to a TDD approach because it forces developers to examine the known, the unknown the boundaries between them BEFORE writing a bunch of code.
TDD debates aside, when developers can’t tell the difference between the code which is technical debt and the code that is part of the application backbone, highly coupled code is written. Code written this way makes new bad, buggy code invisible because it’s camouflaged with all of the other bad, buggy code. Sometimes it even makes code known to be bad seem necessary. This provides bias toward a quality downward spiral and reduces the positive effects of writing high quality code. What’s worse is when the bad practices are not contained, it is actually more expensive, more difficult, and less effective to follow good coding practices.
Many of us learn new technologies, techniques, and even the problem domain on the job while fixing (more like tinkering with) the application. We wouldn’t likely trust a bridge who’s builder learned how to build a suspension bridge while putting this one together and never went back to start over when things didn’t go according to plan. We wouldn’t likely trust a doctor who hasn’t practiced in med school and residency. We wouldn’t likely trust our money with an investor who invests in stocks and then sees if the stock price rises. If we want the other professionals to try out their ideas before putting us and our assets at risk shouldn’t we do the same thing with the code we write for these professionals?
So what then, are all projects using new technologies doomed to be rewritten? I don’t think so. If we to plan, prioritize, keep within an appropriate scope, and pause long enough to learn and try new things in a environments outside of the application success will come faster and more easily.
Hacking upon an existing hack is what I call “feeding the monster”. Code monsters are anti-patterns and hacks gone wild. The reason code monsters continue to get bigger is that they keep growing in scope, touching more and more of the application due to their godlike ability to attract dependency. This is not the result of dumb developers. It is probably the result of avoiding design, not taking the time to understand the problems or anticipate or communicate the vision of the product. If our developers don’t understand the purpose of a feature or product how do we expect potential customers to do so?
Forethought and organization are often what is missing from bad code. Developers who do not use the SOLID principals should be encouraged to learn these principals and be given guidance on how to apply them. The time “saved” by giving hackers room to hack will be made up for and then some. Not as technical debt but as shoddy work that if not replaced will be struggled with again and again.
Bad code is not the result of dumb developers (usually) it is the result of trying to do too much without the proper resources and neglecting the right thing for the first thoughtless thing that comes into our heads.
Object oriented code is all about relationships between objects. Coders who believe their coworkers are all fools tend to write objects that are difficult to work with, not eager to explain themselves, and perform erratically and irrationally. If you constantly find you are surrounded by idiots you may want to ask yourself if you are being unreasonable, if you are being closed minded, of if you have chosen the right profession. Opening your mind up to the idea that you probably work with rational, well-intentioned people will probably make you a better coder and it might even make you less grumpy. If you are surrounded by jerks who do not engage in the exchange of ideas who do not care about their customers or the durability of the code you are building together then I suggest you find a new place to work.
What do you think? Are good programmers incapable of writing bad code? Are bad programmers incapable of writing good code? Or is it really the way we look at coding that gets us into (and out of) trouble?