by Jasper Sprengers

There are plenty of learning resources on software best practices. Sprinkled in between all the well-intended advice are warnings about common pitfalls. We could do with a lot more of these warnings and think about why we keep doing the same things wrong. What makes anti-patterns so irresistible?

Stamping out bad habits

Many famous rockstars are self-taught and often received no formal music training at all. Not so in classical music. Any book that claims you can teach yourself to play the violin or become an operatic soprano without the aid of a tutor sells you a false promise. I must have paid my cello and singing teachers slightly more than I ever spent on university tuition fees (granted, these were only 700 euros a year in the Netherlands at the time). None of all this music teaching has brought me any monetary return on investment, whereas my programming hobby has paid out nicely. Sure, I must have consumed hundreds of books, blog posts and tutorials, and of course I wrote many thousands lines of code on hobby projects. However, all of this was largely unsupervised. I learned the most from working alongside more experienced programmers. These people didn’t only teach me new things, but most importantly they weaned me off some ingrained bad habits.

Education is as much about showing how to do things properly as it is about stamping out the bad habits that come natural but are nevertheless wrong. You really need a teacher to do the latter, especially for any pursuit that is more physical than intellectual, like sports and the arts.

Coding isn’t that much different. Yes, if you’re an experienced Java programmer you can teach yourself Kotlin, no problem. But when it comes to more generic principles you mustn’t assume that just knowing the right ways will always keep you on the straight and narrow.

Bad habits are not a popular subject

Here’s why diet books don’t work: they suggest that all it takes is pointing out what healthy foods you should eat. Yet we all know that staying away from the fattening junk is the really hard part. There’s no shortage of books on healthy coding practices. There’s the clean coder, the pragmatic programmer, the humble programmer. Frankly, I’ve heard quite enough success stories. Give me the book “how to avoid being a dysfunctional pedantic twit” or “We wasted everybody’s time, tens of millions of dollars and still have nothing to show for it”.

Code quality is as much an indicator of underlying personal attitudes and team dynamics as it is of developer proficienty. I believe that both good and bad patterns result from only a small number of positive and negative attitudes and behaviours. These are important markers for the success of a software project.

The hall of shame is no laughing matter

You can’t write great code if you’re an inexperienced programmer, but you can certainly always write bad code no matter your experience or IQ. Anti-patterns aren’t always committed by bad programmers but they’re always the result of unconscious bad habits.

The hall of shame is of course the daily WTF, where the most glaring incompetence is exposed to ridicule for the coding community, thankfully anonymous. What bothers me though is the implicit assumptions that we, the readers, know better and have nothing to gain from it but a chuckle. But anti-patterns are no joke. Just because you can avoid beginners mistakes doesn’t mean you’re immune to committing the really major cock-ups. I can warmly recommend Scott Rosenberg’s Dreaming in Code about the ill-fated Chandler project, which comprised some of the best programmers, hand-picked by none other than Mitch Kapor of Lotus fame. Chandler, you ask? Exactly.

My personal top 3 of good habits

Here’s my personal top three attitudes that are most instrumental to building quality software and teams:

Pride of collective ownership.

Without this you will care less for your own quality and that contributed by others. Note that you can be be proud of a particularly clever bit of code, but that doesn’t count if it confuses your colleagues or conflicts with their code. So you need…

Without this you will care less for your own quality and that contributed by others. Note that you can be be proud of a particularly clever bit of code, but that doesn’t count if it confuses your colleagues or conflicts with their code. So you need… an attitude of always wanting to help, really the same kind you can often find in family-run hotels or B&Bs, where nobody gives you the feeling that it’s just a job to them.

Meanwhile you have to stay firm about quality and professional standards, Most software is written for the long term. Others will probably be working on it after you leave. You have to display good stewardship, which having an eye for the long term.

Especially points 2 and 3 can be at odds: it means having to say no more often. It means standing your ground ocassionally and insist that some things are non-negotiable.

Self-centred indifference

I confess that all this is hard. Just put the above list of saintlike qualities in the negative and you get a sense of what we’re battling with on a daily basis. Unclear management commitment to a product’s roadmap kills the sense of collective ownership. This lack of commitment leads to indifference about quality, and there’s nothing more contagious than indifference. Code quality will suffer, and poor quality is a slippery slope. There’s just no fun if the best you can do is make things slightly less bad.

Self-centred attitudes on the other hand lead to a host of toxic effects within a team: it’s being overly confident about your own abilities, bragging, tunnel vision and envy. It’s a cliche that programmers are on average more communicatively inept, socially awkward, pedantic and self-centred, but it wouldn’t have become a cliche if there wasn’t a grain of truth nonetheless. Several grains actually. Maybe even enough to bake a small loaf.

The dangerous short term

The upside about these two team-killing attitudes is that they stand out to the good observer and you can act upon them. There is another category of bad habits that seem less destructive on the surface because they don’t do as much harm to team morale, but can be equally damaging to long-term product quality. I’m talking about being too focused on short term result and not looking back at lessons learned. We tend to do it because code is written today, to be shipped next week. We don’t exactly please our stakeholders if we delay the release to upgrade a few old libraries. So this never happens until these libraries are ancient, unsupported and a security vulnerability.

There’s a host of anti-patterns that come from bad housekeeping and not looking back: the boat anchor, the dead end, the Lava Flow, Continuous obsolescence. And what else but pride and tunnel vision could lay at the root of the Golden Hammer and intellectual violence?

Vegetables and raw nuts

If clean code is vegetables and raw nuts, anti-patterns are hamburgers with coke and ice-cream. Their appeal is much like junk food: we’re drawn to it naturally. Sometimes we feel the need to impress others and sometimes some private concerns outweigh any code you’re working on at the moment so you just want it to work quickly and go home. The occasional anti-pattern becomes a problem if you’re unwilling to learn from your mistakes or ashamed to admit to them. I’ve made tons of mistakes. There aren’t many pieces of code I’ve written at any stage in my career that couldn’t have been improved at a later glance.

There are always people who are deliberately vicious and manipulative about taking the maximum amount of credit for the least amount of work. Rest assured: they tend to work in the financial industry and don’t wear a t-shirt to work.