Common AntiPatterns

While at UberConf 2010 I had the opportunity to attend a talk on AntiPatterns put on by Mark Richards. There are many AntiPatterns that exist in the software world, but Mark decided for this talk to focus on seven that he considers to be the most common. The following is a quick summary of Mark’s talk.

What are Patterns?

A pattern is a repeatable process that produces positive results each time. The main reason patterns were developed were to help improve communication between developers. Design patterns allow developers to use a common language to convey complex design ideas in just a few words.

What are AntiPatterns?

AntiPatterns are things we repeatedly do that produce negative results. The example Mark used was Gambling. Even though repeating this process produces negative results, we still do it again and again.

Factors that cause Anti-Patterns
  1. Haste – When project deadlines are tight, budgets are cut, team sizes are reduced, in these pressure situations we tend to ignore good practices.
  2. Apathy – Developers who really don’t care about the problem or the solution will almost always produce a poor design.
  3. Ignorance – When a developer either lacks knowledge of the domain or of the technology being used, that ignorance will result in antipatterns being introduced.

Seven Common AntiPatterns

There are many, many antipatterns in software design, but these are some of the most common.

1. Cargo Cult Programming

Using design patterns, techniques, or new technologies before really understanding them. Often as developers we jump into new technologies because they are interesting and we want to use them so we try to fit it in somehow, whether or not it is necessary for our project. This can lead to introducing a new technology or pattern when it is not needed and add unnecessary complexity.
Avoid it:

  • Don’t introduce a new technology unless it is absolutely necessary.
  • When you see some code you aren’t sure of, take the time to read and understand it.
  • Take the time to read and understand a technology you are currently using or considering using.
2. Lava Flow

An old area of the code is never updated or touched because everyone on the project is scared to touch it. Often this occurs because none of the original developers who wrote the code still work at the company. Some signs of lava flow are when you have large blocks of code commented out (“Why was this commented out, was it needed?”) and also when there is dead code still hanging around in the code base.
Avoid it:

  • Remove the commented out code.
  • TDD with meaningful regression tests.
  • Use tools to find dead code.
  • Use interfaces to isolate the mess and also help locate dead code. If no path through the interface uses it, then it is safe to remove the code.
3. Parallel Protectionism

Code becomes so complicated and fragile that developers start copying the code and making changes to the copy rather than extending the original code out of a fear of breaking some existing functionality. Problems with this antipattern are that not only does it introduce duplicate code to the product, but now if a bug is found we now have two places to apply the fix instead of just one.
Avoid it:

  • Look for duplicate code at all levels.
  • Split up complicated areas of the code into smaller chunks.
  • Avoid creating complicated tricky code that developers will be afraid of. Focus on readability over clever tricky code.
4. Accidental Complexity

Introducing unnecessary complexity to a project out of ego by trying to out do other developers by accomplishing the same task in less lines of code (“Wow, look at this amazing piece of code I wrote!”). This can also happen by accident when a system is built one method at a time without any real overall plan.
Avoid it:

  • Focus on simple designs.
  • Write readable code instead of “tricky code”.
  • Frequent code reviews, or better yet, pair programming!
5. Object Orgy

An objects private values should never be exposed for modification unnecessarily. This is usually caused by poor encapsulation. For example: generating setters for every property in an object is NOT encapsulation. By always generating setters you are creating an object where it’s state can be invalidated at any time. The state of an object should be initialized by a constructor. Object Oriented programming is about object state, not getters and setters.
Avoid it:

  • Use proper encapsulation.
6. The Blob

A class or package in your system that does far too much. The catch all for any code where the developer is not sure where to put it, or is just too lazy to create a new class or package. Also what can happen is developers will put code somewhere else simply because it is smaller and easier to work with, even if it is not the correct location. This antipattern is usually caused by a lack of proper object oriented design skills on a team.
Avoid it:

  • Code reviews or pair programming.
  • If you can’t describe a classes functionality with a single sentence, then it has too much responsibility.
7. Golden Hammer (Most Common)

Using the same technology or technique to solve every problem. For example: “I like Perl, Perl is the best language ever, it is perfect for any problem”.
Avoid it:

  • Be familiar with many programming languages, technologies, tools, and know each of their strengths and weaknesses.
  • Set your personal preferences aside and always pick the best tool/technique for each problem you are trying to solve.

Mastering Design Patterns

While attending the SD West 2008 conference I made sure not to miss any talks by Robert C. Martin. This talk was excellent. The room was packed with standing room only available in the back. Robert C. Martin went through a number of common design patterns. There is no reason for me in trying to summarize them all, just get the book. In the talk we went over the following design patterns:
Design Patterns

  • Adapter
  • Strategy
  • Template
  • State (two level, and three level)
  • Observer
  • Model View Controller
  • Model Presenter
  • Command
  • Actor Model

This was an excellent talk.

Better Software No Matter What

The talk from Scott Meyers was excellent. He is a great speaker and really understands the root issues that lead to many quality issues in software. Mark has already posted some comments, so I will just touch on a few common issues Scott kept stressing time and time again.

One of the basic principles of developing quality software is consistency, from the UI to the code and even the unit tests.

Without consistency you will never be moving toward quality software. One of the ways to go about doing this is to provide developers with a set of guidelines and best practices. If developers are not given this guidance they will each develop code and unit tests as they feel the tests should be done, which is fine, but will never result in consistency. To be able to move towards consistency provide the development team with guidelines for: code styles, naming conventions, unit test layout, refactoring standards, etc.

The point he stressed was the most important of all, above everything else is “Interfaces must be easy to use correctly, but difficult to use incorrectly”. He was talking about not just user interfaces, but all the way down through the classes, the methods, the APIs, etc. If the interface is not clear then you have failed to fix the number one issue. If the user interface is confusing, users will leave, if the code is hard to understand, developers will be less inclined to refactor and instead will make the smallest change possible every time which will lead the project further and further from being quality software.

The afternoon talk from Scott Meyers was just as good as the morning talk. I have to say that his talk is one of the most useful presentations I have ever attended, including conferences I have been to in the past. Scott Meyers really knows a lot about software quality and explains it well in his talk. He stresses in the talk about how ALL bugs are an embarrassment, not just big issues but even minor issues that are considered “cosmetic” and often ignored. Minor issues are often the ones that do not prevent a user from performing the task they wish to do, but are enough to cause annoyance and frustration which does not create a good impression of the product.