Anti-Patterns: Do's and Don'ts
I'd probably describe anti-patterns as 'what not to do' but SourceMaking has a more succinct description:
An Anti-Pattern is a literary form that describes a commonly occurring solution to a problem that generates decidedly negative consequences.
Before I get into some of the more common ones I thought it would be worth flipping the coin and starting with explaining what design patterns are.
What are Design Patterns?
Design Patterns have their roots in Architecture; in the 70s Christopher Alexander's pattern language was influential in simplifying new projects by enabling complex problems that had been solved at many different scales to be used. In his book A Pattern Language he covers 253 patterns, from ways of reducing left-hand turns and four-way intersections to reduce congestion to the direction to face parts of a house where people sleep (East so they wake up with the sun).
This was then taken on by software developers late 80s and Design Patterns: Elements of Reusable Object-Oriented Software was published in 1994 by the so-called "Gang of Four"; this book is a tome for most work with software design patterns and thankfully it only mentions 23 patterns!
But I'm not going to talk about Design Patterns as I still find them a little abstract and difficult to describe, and without a decent knowledge of object-orientated programming it probably won't be useful. If you want to read more I'd recommend starting with the creational patterns like the Builder and Factory method patterns.
Anti-Patterns in Business
The good thing about anti-patterns as a concept is that it doesn't only apply to software, we all see it and experience it every day.
Design by committee
As we regularly work with graphic designers to build websites, we're experienced with working directly with designers, and trust them as they're the experts in their field. While good ideas can come out of committees, good designs rarely do.
This cartoon from XKCD demonstrates typical university home pages and highlights the sort of designs that might come out of a committee…
On a related note, it's interesting to see how people can change when they're in large groups and groupthink is an example of that. It's a psychological phenomenon where the need for harmony or conformity in the group results in irrational or dysfunctional decision-making. Rather than challenging alternative or controversial viewpoints, conflict is avoided so that a consensus decision can be agreed. In these situations, critical thinking and creative thinking are squashed.
To avoid this, it's worth appointing a devil's advocate, or like the movie World War Z, a 'tenth man', whose purpose is to disagree, no matter how improbable the idea. In the movie they built a wall to keep zombies out based on a single word when the rest of the world ignored it. While this is an extreme example, it's well summed up by the following quote:
When you find yourself on the side of the majority, you should pause and reflect.
I've definitely experienced this in past jobs (not at Orantec!) and there are very few situations where this is an effective approach. The biggest problem is you don't feel like you're trusted and you're always looking over your shoulder, when you’re not writing performance reports. While it’s important to get the details right, this places too big an emphasis on quality, when there are other ways to achieve it without causing mental health problems.
You’ve probably heard of typecasting in movies. It’s often hard to distinguish the difference between the characters Tom Cruise, Nicolas Cage or Arnold Schwarzenegger play in their movies. They don’t often play characters outside their normal range, and I’m pretty sure Tom Cruise plays the same character in every movie: himself.
Being typecast in a job means you’re in a role that is safe, predictable and has a very narrow range based on what you’ve done in the past. In these kinds of jobs you stop growing and your potential is ignored. Thankfully at Orantec I have the opportunity to work with the wide range of technologies and the full development stack, and I must say that’s pretty enjoyable!
If you’re limiting your employees in this way, you could be missing out on their full range of talents. Think of people like icebergs, you only see the tip, most of their talent is under the water.
When it comes to project management, beware of scope creep, which is generally considered harmful. It refers to the continuous growth and unending changes to a project's scope.
As part of our project management, we value feedback and plan it into our projects, but we do want to give you a product you're happy with, and constant changes are not going to make anyone happy. Some changes are clearly inevitable, but they can only be managed with good communication.
Buzzword Driven Development (BDD)
Even if your decision may be criticised later – like whether or not you’ll change your app infrastructure for the latest craze – at some point you do need to make a choice and act. Changing the way you work constantly is counterproductive however, so it’s better to avoid being too tempted by BDD. Dr Richard Wilson shared at the inaugural Cardiff Tech Talk, his decision to keep Durandal for his company’s application infrastructure, instead of changing for AngularJS, or for Durandal’s successor Aurelia.
Anti-Patterns in Software
Reinventing the Square Wheel
You've probably heard of reinventing the wheel, wherein you're duplicating a basic method or building block that's already been created or optimised. The ‘square wheel’ is a wheel you create that’s actually worse than the original.
This typically happens when a developer is unaware of or doesn't want to use the tried and tested, standard solution. You can combat this by continually learning and challenging yourself.
At Orantec we want to produce high quality solutions while knowing where to stop, that is when the improvement that can be achieved is not worth the time, effort and money necessary to reach it.
Gold-plated HDMI cables are a good example as the gold plating will not significantly improve the picture quality, it mostly makes for very expensive cables.
We build a lot of user forms and controls that need user input within applications and we find it can be frustrating for both the user and the client. How many times have you filled a form in and clicked on the Magic Pushbutton - the button on a form that connects your fancy front end to the data –to find out that most of what you had typed into the form was wrong? Validating data after each entry and not only after submission helps to improve user experience; that's why we’re aiming to provide useful form validation and feedback and are no big fans of magic pushbuttons.
You don’t want your code to resemble spaghetti, it's twisted and tangled and it makes a mess trying to pick it apart. If you look at an application or website, it should be logical to follow through and it should be well-structured so changes you make have predictable results.
While the fork and spoon method might make eating spaghetti easier when it comes to coding it will just cause you a lot of headaches.
One of the biggest headaches is the race hazard (or race condition) which is a type of bug that only occurs when events don’t happen in the order they were expected to. Race hazard has its roots in logic circuits where 2 signals were racing each other to influence the output first.
These issues in the 'works on my machine' category as they're usually hard to reproduce, it's often better to update the design to take this into account and not make any assumptions regarding the ordering of events.
A term from amateur radio, a boat anchor is an old piece of equipment, generally large, obsolete and only used to stop you from moving.
Then it comes to software, this refers to unnecessary code; it can be a feature that is no longer needed, or more commonly a web browser that is no longer used or supported (such as Netscape 4 or IE4). At Orantec, as we keep a large amount of our projects in source control it can usually be safely deleted and easily restored if it is needed. The problem with this sort of code is that it causes undue complexity and makes maintenance more problematic for very little, if any, value.
It's common in programming to write a pattern or function which can be reused over and over. This principle is often referring to as ‘Don't Repeat Yourself’ (DRY). Keeping things DRY means that changing one thing doesn't have a significant ripple effect and doesn’t require a large amount of rework.
When you're in the early stages of programming an application, you might do this unwittingly, so make sure it's something you make an effort to reduce or you'll just double or triple the work you need to do later.
It’s worth remembering the opposite of DRY is WET or "We Enjoy Typing". No one really enjoys that!
"If all you have is a hammer, everything looks like a nail" - Maslow's Hammer
You shouldn't make assumptions when it comes to solving problems, like assuming your favourite tool is always the best solution and relying on it for everything. In the tech industry it's good to fall back on well-tested design patterns, but development tools and software implementation often have a limited lifespan.
I am always looking to improve myself, by keeping up with the latest developments on web technologies, UX design and I try to avoid déformation professionnelle, i.e. taking a web developer's narrow view of the work. It's good to think like an architect, a customer, a doctor or put ourselves in the shoes of our clients to get a wider view of the world.
By trying to improve performance too early in a project, premature optimisation tends to only add complexity, as it makes maintenance and debugging difficult. It’s very common, particularly with databases, to find that your gut instinct on the performance of a query is wrong.
It’s better to combine optimisation with benchmarking and profiling; this means making small changes and testing the result to determine if there was an improvement. This is much easier when you’re working with a simple and elegant design. Any change or optimisation could result in new bugs which need to be balanced with the time spent on optimisation. Is the effort going to provide a good enough benefit?
A lot of the software anti-patterns have what is sometimes referred to as a code smell, and with experience you develop a sense of problem areas. Refactoring code is an essential activity, allowing you to look back on what you’ve written to improve its readability, reduce its complexity and improve its maintainability, but that’s a post for another day!
Please take these anti-patterns with a pinch of salt, they’re usually extreme examples but the main takeaway of this blog is that you shouldn’t hesitate to question your working practices and the common solutions that are doing harm. There is most certainly a better way to doing things and you probably won’t have to look far to find it.