Picture of stu

Design Patterns are Code Smells

  • Posted By Stuart Halloway on May 17, 2007

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?

Comments
  1. Bob LeeMay 17, 2007 @ 07:14 PM

    Right on! FWIW, frameworks can alleviate the need for patterns, too.

  2. Ricky ClarksonMay 17, 2007 @ 09:36 PM

    Go on Bob, just say it. No? Ok, I will. Guice alleviates the need for at least the singleton pattern (or at least the usual implementation of it in Java), by providing your instances for you. You just say that it’s a singleton and Guice will always give you the same instance. No more boilerplate.

    (I have no affiliation with any part of Bob Lee)

  3. Gerry LunaMay 18, 2007 @ 02:40 PM

    frameworks can alleviate the need for patterns, too?

    Frameworks are made from a combination of patters to solve a general context problem.

  4. Bob LeeMay 18, 2007 @ 03:22 PM

    Ha ha, thanks Ricky. I would go so far as to say Guice can eliminate the majority of factory implementations (of which singleton is a very common example). It’s like a factory code generator. ;)

    And the method interception eliminates the need for the command pattern. You can look at method invocations as commands, and your users get a much more intuitive API (invoking methods instead of creating command objects).

  5. MittalMay 18, 2007 @ 03:39 PM

    if frameworks can implement all the patterns that shall be great for developers and they can focus on business logic and reduce overall development time..

  6. RyanMay 18, 2007 @ 03:52 PM

    I have felt for many years that many patterns are just recipes for getting around flaws in the language tools. My first OO language was a prototype oriented one (MOO), and then I learned Smalltalk and Self after that—when I first started doing Java & C++ & Python for $$, the concept of ‘singleton’ was just alien to me… This had to be encoded as a pattern.. why? Because the language made solving certain problems hard, and here was this trick we learned…

    The visitor pattern is the classic case of a pattern which is a workaround for lack of sophisticated pattern matching in the language.

    But… If patterns lose their holy status, what will “elite programmers” ask their victims at job interviews?

  7. Vlad PatryshevMay 18, 2007 @ 04:53 PM

    While patterns, as we see them in the GoF book, look really ancient these days, refactoring to patterns happens to be an extremely good trick in doing an instant facelift to an amorphous spaghetty code the is encountered too often in the real world.

    Besides, talking to a certain kind of developers, it is much easier to explain general ideas using “patterns”, since math and logic are often far beyond their mental abilities.

  8. Anonymous CowardMay 19, 2007 @ 12:01 AM

    That’s pretty fucking arrogant, Vlad. But oh well. Spasibo.

  9. JakeMay 19, 2007 @ 04:11 AM

    I agree – I am so tired of hearing about design patterns – pattern this, pattern that. The only truly useful patterns are the ones that programmers know inately or that common sense dictates…

  10. Richard L. Burton IIIMay 19, 2007 @ 07:21 AM

    Have you ever heard the saying “Its your upper lip that you’re smelling”? The ‘code smell’ is simply the scent of a dumb developer. If I had to compare it to something, I’d go with those people that believe the second coming of Jesus will code in Ruby. They’ll make every effort to show its magical powers, even if it means comparing Ruby to an old Java Framework.

    People need to stop blaming patterns, frameworks, and so on, and start focusing the blame on where it belongs. Ignorant developers that abuse what ever they can get their hands on to beef up their resume.

    Guns don’t kill people. The pissed off man or women with a mental defect kills people.

    Besure to lock up your Ruby code, far away from bad developers.

    Best Regards, Richard L. Burton III.

  11. LispnikMay 19, 2007 @ 09:56 PM

    Well thanks for stating the obvious, but what are you going to do? Stop in the middle of your code review example and request a rewrite in Dylan?

  12. Stuart HallowayMay 20, 2007 @ 12:45 AM

    Lispnik: ROFLOL. I’d love to be in the room when someone does that.

  13. EdMay 20, 2007 @ 04:09 AM

    Well, not every single app in the world can be written in LISP, Dylan, or Ruby. Quit blabbering every single tool is wrong and Ruby is the only way to save your sanity.

    For those that got tired with design patterns, maybe because you can’t handle them? Don’t mask yourself by saying DP sucks and all while the truth is probably that you just can’t handle DP.

  14. MonkeygetMay 20, 2007 @ 09:44 AM

    Design patterns are programming language smell.

  15. VenticelloMay 20, 2007 @ 10:09 AM

    Design patterns are code smell for you? Maybe you are an idiot or you read a porn as design-patterns book :)

    In every good OO language, like Java, the fully use of patterns let you feel good and you’ll have no dumb problems deriving from the not use of it! Then, frameworks are only a good combination of standard patterns resolving a particular set of problems. Don’t forget it.

  16. Steve LMay 20, 2007 @ 01:31 PM

    Patterns are just a common language. When talking to any programmer I can say “X is a singleton and Y is a facade” and they will know what I mean; without the patterns I’d have to say “the system will ensure that there is only ever one instance (do you need me to explain instance?) of class X, and…” This is independent of the language used. The fact that some languages/frameworks make implementing some patterns trivial is beside the point.

  17. VictorMay 20, 2007 @ 08:13 PM

    Do I smell a “Refactoring FROM Patterns” book in the oven?

    As a Java and C# developer who has recently started programming in Ruby, I can tell you that there are a lot of patterns I’m having to unlearn because of the the differences in the language. Different tools bend in different ways, just like various building materials require different considerations and construction techniques.

    Using Ruby is less like working with a hammer or wrench and more like a Swiss Army knife. Every now and then you find a little hidden tool you didn’t even know you had in there!

    As to Richard’s comment about guns not directly killing people: perhaps not, but guns sure do make it easier for killers and the mentally disturbed to take out people in large numbers very quickly. And it doesn’t take a lot of skill to point and shoot. Not to mention the inexperienced and innocent who off themselves accidentally each year. I don’t know if the same gun metaphor is applicable to the abuse of software patterns, but I do know there were many times I wanted to blow my own brains out mucking with XML, COM interop, and writing endless factories, adapters, setters and getters.

    I see Ruby and some of the other dynamic languages as more like working with a Samurai sword: you can still do a lot of damage to yourself and others until you know how to properly wield it. And there are the masters and the novices like in any martial art. But not just any crackpot is as likely to pick one up at the local sporting goods store and head to the nearest clock tower in a fit of rage and insanity.

    From what I’ve seen of the Ruby community thus far, it is full of masters and novices alike, with many in between. Only I see a lot less of the attitude of the good vs. the bad developer and a lot more openness to helping newcomers learn ‘The Ruby Way.’ I wish more developer communities were like that.

    “Wax on, wax off…”

  18. Yujun LiangMay 20, 2007 @ 11:50 PM

    I am an experienced developer, I survived many projects before I knew any Design Patterns, then learned them afterwards. After I really understood them, I felt shameful for the code I wrote before, even they run perfectly well for the business operations.

    Last year, I started to work on a project. I noticed sometime similar to my old code. A huge class does everything for 4 kinds of calculation. So for everything big or small, this class has to be visited and changed. I spent one month and turned this one class into 94 classes collaborated with each other in Abstract Factory, Prototype, Singleton patterns for object creation and Strategy pattern for variant situation handling for each kind of calculation and then added the fifth one without concerning any other 4.

    Previous to my change, there were many if-else branches and long methods doing complicated decision making, after the change, each class is organized by its functionality and its product family. If you think these classes as tools you used to fix your home, previous to my change, all tools are stored in a bag without any order and after the change, they are clearly labeled and put on a tool shelf. This is achieved by using appropriate design patterns.

    Of course, we can’t overcome language limit by using design patterns, we know that. This is same as people can’t overcome their life limit by eating food, we can’t just say the food smells.

  19. S SiddiqiMay 21, 2007 @ 02:11 AM

    Hmm…perhaps I don’t follow, but I don’t quite see it that way.

    Design patterns, or more precisely Object Oriented Design Patterns, are more or less useful (albeit with varying difficulties) across all Object Oriented languages.

    Patterns do target particular programming paradigms, but not particular languages.

    The utility of OO patterns may vary as we cross paradigms, or even as we start to use domain-specific scripting languages and frameworks (may I include Ruby on Rails in this category?)...

    Indeed some patterns may even target or presume the capabilities of a particular framework (J2EE patterns, for example), and so the utility of these patterns rest on the context in which they will be applied.

  20. Herr OberstMay 21, 2007 @ 07:41 AM

    1. The notion of patterns was the main invention of that book. If a language supports natively a pattern that means you can (if you really want) forget the Implementation section of the corresponding pattern. You remember: Problem (context), Consequences, Application….do you want to forget when to apply a Singleton?

    2. Patterns serve as mnemonics in communication. ”...and here we will introduce a class, you know, with the private constructor and the static getInst-or-something method”.

    3. Language dependency was stressed enough in the original book. The book was oriented towards imperative languages. Other languages possibly have their own pattern set. And everybody can create new ones.

  21. Jose M. ArranzMay 21, 2007 @ 09:24 AM
    <ricky>You just say that it’s a singleton and Guice will always give you the same instance. No more boilerplate.</ricky> Sure? “just say that it’s a singleton” this is the boilerplate, an IoC tool does not prevent you to know and apply your same old software patterns.

    “No more boiler plate” is a wrong statement, IoC frameworks only reduce the code written: different kind of boiler plate, and fewer lines of boiler plate.

  22. Deepak ShettyMay 21, 2007 @ 01:03 PM

    Inspite of all the UML and other techniques to abstract out “implementation” details , i havent yet come across a system where the implementation language(or its limitations) hasnt mattered. Im not sure why you feel designing for a specific language is a problem.

  23. MikeMay 23, 2007 @ 04:59 PM

    What monkeyget said.

    So some langages have more elegant approaches that let you avoid certain explicit design patterns. That doesn’t mean the same explicit patterns used in other languates are a “code smell” in those other languages. Context, remember?

    It probably should have been something more like: “design patterns imported from other languages may be a code smell”.

    Of course, that wouldn’t attract as much attention, would it?

  24. David HamiltonMay 25, 2007 @ 07:01 PM

    Stuart – I think your post is addressing ‘code patterns’ rather than ‘design patterns’. Your main worry seems to be how to relate design patterns to code reviews, and specifically how to deal with programmers who have applied code examples of design patterns in a cut/paste antipattern manner.

    As I point out in my blog – http://www.jiffle.net/node/106 – I think that each team needs to formulate its own set of acceptable code templates, adapting each pattern to the language and framework being used.

    Surely it makes more sense to agree – as a team – versions of required patterns that have been adapted for the context that you are using. Then these can form a positive basis for code reviews – a ‘do this rather than that’ approach rather than a ‘don’t do that’ approach.

  25. StuMay 26, 2007 @ 02:11 AM

    David – I find myself mostly in agreement in with your comment here, but less in agreement with the elaboration at http://www.jiffle.net/node/106. The devil is in the details, of course. Templates, like patterns, are useful but also a danger sign. Are they conveying shared understanding, violating the DRY principle, or some of both?