Design Patterns are Code Smells

In the original GoF book, the authors made it clear that when you are doing design patterns, implementation language matters:

The choice of programming language is important because it influences one's point of view. Our patterns assume Smalltalk/C++ language-level features, and that choice determines what can and cannot be implemented easily. (Design Patterns, p.4)

Unfortunately, this message has generally been lost, and programmers all too often use patterns as recipes. Martin Fowler explains the difference:

Recipes tend to be more particular, usually tied to a particular programming language and platform. Even when patterns are tied to a platform, they try to describe more general concepts.
If you have seen a Java or C# application that looks like a C++ recipe collection, you know the damage that conflating these two concepts can cause.

Regardless of how you distinguish patterns from recipes, the programming language that you think in will be the programming language you design for. This is one reason why the Prags encourage everyone to learn one new language a year. You will still design for the union of the languages you know, but at least you will not be hopelessly provincial.

Language advances kill patterns-as-recipes. Back in 1998, Peter Norvig argued that most of the original GOF patterns were invisible or simpler in Dylan or Lisp. Since then, Greg Sullivan has made the same point for Scheme. Jan Hannemann demonstrated the same for Java+AspectJ. Design patterns do not perform well as recipes. They are seasonal at best.

At code level, most design patterns are code smells. When programmers see a design pattern in a code review, they slip into somnolent familiarity. Wake up! Is that a design pattern, or a stale recipe from a moldy language?