Software development anti patterns. How to ruin your product.

Christoph Nißle
11 min readSep 10, 2022

--

You are probably well aware of patterns. Design patterns, organisational patterns, behavioural patterns and many more. When it comes to software development we are confronted with all sorts of those. And especially with knowledge about Conway’s Law we know very well how those are influencing software products that are, or sadly could have been great.

An anti pattern can be many things, it can be a proven way to be unsuccessful that can be observed over and over again. It can be a wrongly applied pattern. But what it is in any case, a very sure ticket to being your own impediment.

Photo by James Harrison on Unsplash

Anti patterns

Manual testing over automated testing

Let’s start off with a heavy gun. As a QA engineer, your role is to assure quality. It can be surprisingly hard though to prove that a software does what it is supposed to do.

In well-intended efforts, I have seen that lead to either extensive, complex and long-running test suites, that only can be operated and maintained by them. Break randomly and only add to the complexity of the product.
Or for a sign of showing leadership and having everybody pitch in to check manually. Quickly phrases like that appear in the face of a bug: “It hasn’t even been tested by the developer”.

In my opinion that is so very dangerous, because it insinuates that developers weren’t trying well enough to do it right — even if it might be so, it is never that easy. Secondly, it marks manual “clicking-through” as testing. To me that is not testing, that is sampling. And suddenly the company talks about “testing” and by that means “manually clicking through an application”. Well, how far from quality are we now?

Heroism over built-in improvement

This has got to be one of my absolute favourites. I am very likely to walk into that trap on my own, which is why I am very, very sensitive to noticing that.
We often have built-in mechanisms for improvement.

One of the most popular ones is a regular retrospective or other self-improving checkpoints. One of the assumptions here is, that successful products only can be created in a team effort. So having sustainable and collaborative processes is essential.

When projects get into crisis or deadlines close-in other mechanisms start to shine through. The one developer who stays up late to fix bugs, the QA engineer who starts voicing her findings in chats instead of the issue tracking system, the DevOps engineer who puts in weekend hours to save 1 minute in deployment time and … you get the picture.

So what’s the problem here? They do all good and talk about it. They get praised, and things are better than before. Perfect, right? The project manager comes along and praises the quick fixes, and the effort put in and in the next business lunch, there is extra special mentioning of that situation and how brilliantly it was solved. Everybody is happy.

Well, I think, not so much. Against popular belief that does not make everybody aspire to be the person in the spotlight. What it shows is that team efforts are for the bin, because in the end, it is the single hero that saves the day. It also tells the imperative that improvement processes are useless because we have heroes.

Don’t get me wrong, excellent people are perfect to have. But if you aim for results that are more, than the sum of every single person provided resources, that is not how

Don’t create Brent (Recommended read: Phoenix Project), create team players.

Domain Guardian

Domain guardians are experts on a specific part of your software product. You can ask them almost everything. They don’t just know every single bit, they’ve probably written it as well.

You find them because they do most of their work in only that part of your codebase and even though they enjoy showing their pull requests around, there is usually nothing but approval checkmarks on it because nobody can give actionable feedback anyway.

Additionally to that, they eyeball very closely when others touch “their” code. Nothing seems thought through well enough, there are always things they would have done differently and they tend not to forget to highlight that.
The problem with them is, that they do not just protect the part they’re working on they quickly become the only person capable of maintaining and operating that part.

Help them find a way out of their domain, mentor others into it and work on other parts more often.

Micromanaging

Surprise, it’s me. Micromanagement. 2022 and I am still alive. Usually, companies try to hide their micromanagement practices. Why, you might wonder? Let me make that very easy:

Good people do not join when they feel they could be micro-managed. Good people leave when they are micro-managed.

Managers, so-called leaders, you need to get that into your heads. Software engineers love solving problems and very likely enjoy working in a process that allows them to thrive at solving problems. Hire monkeys if you want to micro-manage. If you want engineers. Don’t. Period.

I am not going to argue with systems theory, organisational patterns or whatever is out there. You know. If you do it any way you need to understand that you are driving people away.

Reprimand in public and praise in private

Wait, wasn’t it the other way around? If it weren’t an anti pattern, yes.
It is just such a good rule of thumb to praise people in public and criticise them in private.

I have never seen that end well if public blaming became a habit. That said, I also always believe in good intentions, so assuming everybody is operating in good faith. So often the display of that anti pattern can be frustration, pressure, helplessness, bad habits and similar.

We have all been sitting in meetings where someone else or a group of people has been criticised in front of others. That is not just demeaning for the criticised parties it is also very uncomfortable for everyone listening in. And on top of that, it rarely is necessary and rarely helps.

As Kim Scott states in Radical Candor:

A good rule of thumb for guidance is praise in public, criticise in private.

Public criticism tends to trigger a defensive reaction and make it much harder for a person to accept they’ve made a mistake and to learn from it.

Public praise tends to lend more weight to the praise, and it encourages others to emulate whatever was great. However, this is a rule of thumb, not a hard and fast rule.

While it always depends on the context, tearing someone a second one in front of others, raising voices or target distress towards an individual will set your collaboration and team-building efforts back to start, if not even worse.

Sweat shop

Very often business is driving timelines while engineering does its best to estimate and fulfil realistic aspirations of the business. I’d like to see that as a mechanism of checks and balances. It keeps the business from promising too optimistically and prevents engineering from being all technocratic and playing around to the last bit of perfectionism.

Obviously, that is a big back and forth and there are many fine lines to be crossed. Sometimes insights into engineering need to be more detailed, sometimes more loosely. It is basically hard to tell. What is very easy to tell though is, when it went wrong:

The moment business treats engineering like a sweat shop. Under pressure, those burdens fall often on single engineers or whole teams. It happens when the timeline creators stop seeing bigger pictures and stop listening to engineering. When they feel the need to “tighten the grip” for a “short time” and then get back to normal.

The way “back to normal” usually never happens, and if it does, it is way harder than the way into was. Business bulldozing over-e

Don’t let your mouth write a check your ass can’t cash

Do not promise something that you cannot keep. It does not get much easier than that. Where does that happen, and why? I bet you have experienced that a couple of times already. Also, I believe often it is in good faith — well, not towards everyone, but towards the person, the promise has been made.

It is once again a sign of distress on a timeline or project or organisation. Two situations come to mind.

Firstly, in contact with clients, somebody offers timelines because they feel that sounds reasonable, feasible and realistic, but failed to consult with engineering. Yes, that might come down to a problem of missing transparency to form well-informed decisions. It also leads to promising timelines the person promising does not have to keep, but engineering. The project manager often states things like they have “put their heads on the lines” to pressure engineering. Well, don’t promise what’s not yours to keep. You find yourself quickly in the sweat shop, you don’t want to be in.

Secondly, deliverables have been delayed and the situation has escalated so the project manager puts the chief project manager in play who then promises a new timeline. Again without consulting with engineering. Been there? Just don’t. Be honest, be realistic.

Many battles of that world have been lost because the armies of the parties involved in the conflict have been organised through a culture of fear. People started to be afraid to be honest about timelines, about incidents, about impediments, because they knew it would reflect badly on them and the person “putting their heads on the line” on the top would just not have it. So they started creating falsely optimistic reports. And the decisions on top have been made based on wrong information. Not to get started about what this non-respectful and non-appreciative way of working with each other does to people.

You want people leaving and melon reporting? That’s how you get it. Melon reporting? Green on the outside, red on the inside. Enjoy building a good product with that.

Defer only short times

This is something I have had to learn the hard way. You and your team did announce a big release. Let’s say three months in advance. The day comes, and you know it is going to be very close, you might even not make it. You are not at the place where you have cut your features and whatnot in a place you can just leave stuff out. It is getting messy.

On the day of the release, you have to admit, that things are not going to work out. You have to defer the release. Do not make the mistake to defer by just one week or similar. People tend to want to soften the blow of the deferred release by keeping that timespan small.

What that does is, it just extends the stress phase everybody had, and adds to it. How is that supposed to make things better? You need a timeframe that allows for everybody to disengage, take a step back, breath, recover and then plan on how to salvage it. Because now you want to be right with your release.

In that example, give the team a month. Defer, announce and really make it happen. Don’t add to it. Just fix it. (Really, DO NOT ADD TO IT! This is _not_ additional time, this is the time needed, that was missing in the first place).

Low truck number

The truck number is the minimum amount of people that need to be hit by a truck that leads to project failure or stop.

A high truck number means that the knowledge and capabilities to bring your product to success are distributed well and the risk of failure because of sickness, quitting or other things that keep people from working is low.

A low truck number on the other hand means that you probably have too many domain guardians, too many specialised people and way too little collaboration so that factor gets a relevant number.

After all, this is about distributing knowledge and training, which is good. Because that’s something that can be achieved quite easily if you are willing to put in the hours for that.

Just one more thing (The Steve Jobs nobody is waiting for)

Right before the deadline. The release is done, and about to be published. And here we go: “I feel there is just one more thing missing”.

From poor planning, bad estimates, too much work in progress, last-minute requests, opinionated feedback, and people feeling left out to simply not respecting the effort that has gone into making something complete this pattern has many faces.

It can be PR, a release, a simple issue in a ticket system. Often displayed when the value of “getting something done” is not well understood.

It is a gateway to reducing quality and leads to all sorts of bad anti-patterns. Skipping testing, rubber stamp reviews (not really looking at it, just approving so it is out of the way), and others.

Create a habit where you keep the timelines. One more thing? Perfect, there is always the next time.Endless refactor

Endless refactor

We’ve all been there. We have learned that legacy refactoring in small amounts is healthy. I am not getting into the argument that this is not really what refactoring was about in the first place (hello TDD, looking at you).

Often when somebody engages in refactoring, especially planned bits like complete modules or components scope can creep into massive really easily.

Suddenly the refactoring becomes big, or maybe even was planned that way? Removing that old outdated library which was surprisingly weirdly entangled with the complete codebase turns out to be way bigger than expected. A parallel universe of branches merges and rebases emerges.

Only very few people know how to navigate that universe and to be honest, rather be done with it than actually finish it. I feel you. This is not what refactoring is about. This is not how modernisation should look like, as well.

Cut it into slices, find a way to go along with interfaces, and create them if they do not exist. Create a very focused scope and make it a policy of your engineering workflow. If you find x replace it with z. And have it as part of your daily routine.

Don’t create those code zombies that in the end, only delay and make engineers really unhappy — and in return, business as well.

Summary

I have just touched a small selection of anti patterns. Believe me, I have seen many more, and there are many more. Some are more concerned with engineering itself, some with the organisation around it, others with the way how work reaches a codebase, or how architecture is done, how project management is done, … the list goes on.

In any case I have also learned, that it is never bad intent that makes them appear. People mean well but sometimes do not know how to get to success without falling into those anti patterns.

A pattern that is applied in a wrong context and often caused by one of those or a combination of:

  • Disinterest
  • Laziness
  • Stinginess
  • Haste
  • Narrow-mindedness
  • Pride
  • Ignorance

I will write more about anti patterns I find in coding, in architecture, in project management, in ... you get the idea. I want to raise your interest and get this set off. Some are easy to spot, some are hidden very well.

As they often show in times of crisis, wrong behaviour mustn’t be praised. Or it will manifest and your organisational system will reinforce a setup that will lead to failure.

fyi: some links in this post are Amazon affiliate links.

Read more about anti patterns in my story about some specific to software development itself.

--

--

Christoph Nißle

⛰️ Leadership Nerd 🏄‍♂️ People Lover 🎯 Team Player 🚀 Organisational Developer 💻 Tech Enthusiast 👀 Views are my own