30

For every programming project, managers with past programming experience try to shine when they recommend some design patterns for your project. I like design patterns when they make sense or if you need a scalable solution. I've used Proxies, Observers and Command patterns in a positive way for example, and do so every day. But I'm really hesitant to use say a Factory pattern if there's only one way to create an object, as a factory might make it all easier in the future, but complicates the code and is pure overhead.

So, my question is in respect to my future career and my answer to manager types throwing random pattern-names around:

Which design patterns did you use, that threw you back overall? Which are the worst design patterns, the ones that you should consider except in the one single situation where they make sense (read: which design patterns are very narrowly defined)? (It's like I was looking for the negative reviews of an overall good product of Amazon to see what bugged people most in using design patterns.) And I'm not talking about Anti-Patterns here, but about Patterns that are usually thought of as "good" patterns.

Edit: As some answered, the problem is most often that patterns are not "bad" but "used wrong". If you know patterns, that are often misused or even difficult to use, they would also fit as an answer.

2
  • Most patterns make future change easy on some axes of change, but they can make changes harder on other axes of change. The gang of four book is particularly good at saying when a pattern is applicable. Many subsequent books on patterns miss this point. Take the Visitor pattern as an example. It makes it easy to add new tree traversal algorithms, but it makes it harder to add new kinds of nodes to the tree. It also allows the traversal algorithms to be in a higher layer than the tree. You need to consider which axis of change is least stable and design to make changes along that axis easy. Jun 17, 2014 at 17:14
  • All of the ones in the 'Gang of Four' book.
    – Miles Rout
    Oct 13, 2016 at 3:59

12 Answers 12

41

I don't believe in bad patterns, I do believe that patterns can be badly applied !

  • IMHO the singleton is the most abused and most wrongly applied pattern. People seem to get a singleton disease and start seeing possibilities for singletons everywhere without considering alternatives.
  • IMHO visitor pattern has the most narrow use and almost never will the added complexity be justified. A nice pdf can be gotten here. Really only when you have a data structure that you know is going to be traversed while doing different operations on the data structure without knowing all the ways in advance, give the visitor pattern a fighting chance. It is pretty though :)

For this answer I only considered the GOF patterns. I don't know all possible patterns well enough to take them into consideration also.

4
  • I see very few uses for Visitors. Singletons...don't get me started. If the situation is not perfect for one, don't use it.
    – Michael K
    Feb 17, 2011 at 19:47
  • 1
    There may be very few uses for Visitor, but when there is it certainly solves problems. My understanding is that Vistor is essential to LINQ. Feb 17, 2011 at 20:10
  • 13
    The Visitor pattern is critical for reducing (or eliminating) cyclomatic complexity in a software program. Any time you have an if/else tree or a switch statement, odds are high that a Visitor can replace them, offering guaranteed execution and compile-time checking. The Visitor is one of the most powerful patterns I know of, and we use it regularly with great effect. It makes testing a dream as well. Sep 21, 2013 at 4:15
  • @LesHazlewood Isn't then Visitor only a workaround for inadequate programming languages? ML-like languages (Haskell, SML, OCaml, etc.) have algebraic datatypes ("union on steroids") and pattern matching ("switch on steroids") that produce simpler code than Visitor, yet fully checked by the compiler. Compared to visitor, you don't have lots of methods whose share state you need to manage manually via object properties. In ML-like languages, and all case distinctions must be complete, otherwise it won't compile.
    – vog
    Aug 6, 2017 at 20:55
17

Apart from Singleton and Visitor already mentioned by the other answerers, I don't know of "notorious" design patterns. IMHO the biggest problems do not stem from a specific design pattern being "wrong", but rather from developers applying patterns too eagerly.

Almost everyone goes through the "pattern fever" phase when getting acquainted with patterns. Thinking that patterns are the best thing since sliced bread, initially one tries to apply them whenever (s)he sees a possibility. This results in the code getting buried under patterns, where the patterns themselves do not help anymore, just make the code harder to understand and maintain in the long run.

Eventually, most of us gets over this phase and starts to learn how to use the patterns to solve real problems, not for their own sake. Patterns have their price, which is added complexity, and applying any specific pattern is only justified when it pays back for the added complexity by helping to simplify some other part of the system, thus making the code/configuration overall easier to understand and maintain. If this is not the case, it is often better to stay away from patterns, sticking with the simplest solution which could possibly work.

3
  • Absolutely. Patterns are not good nor evil, they are well-applied or misapplied.
    – user4051
    Feb 17, 2011 at 9:32
  • I'd rather teach people the way I learned: OO first, understanding how object relate, and then learning the names of the patterns. It's too easy to think in terms of patterns than what needs to be done. They are a communications tool.
    – Michael K
    Feb 17, 2011 at 19:50
  • Patterns are a means to communicate, not a prescriptive list. If you start with a pattern in mind, you may be misapplying it. If you find one, or the hints of one, in your design, then the pattern catalogues can help you understand what else you may need. Aug 28, 2017 at 15:23
14

I'm going to go out on a limb here and suggest over-use of inheritance. Definitely most applicable in languages without solid compile-time polymorphism support, like Java. Run-time inheritance is a tool, not some kind of one-feature-fits-all wonder.

Other people have already expressed similar to my personal hatred of Singletons, so I'm not going to expand on that here.

10

Singleton. It is on of the GOF patterns which is now more often called as anti-pattern. One of the reasons for that is that Singleton makes code more difficult to test.

6
  • 4
    There are numerous fundamental flaws in the singleton pattern, most are well illustrated in this article by Steve Yegge - Singleton Considered Stupid
    – ocodo
    Feb 17, 2011 at 9:48
  • Slomojo: Nice article. I'm going to call it 'simpleton pattern' from now on :-)
    – Nobody
    Feb 17, 2011 at 10:10
  • 2
    Yes, because some fool misuses a pattern and totally misses the boat on what OO is all about (judging by all the Manager classes he came up with), Of course it is the pattern's fault and not the developers.
    – Dunk
    Feb 17, 2011 at 16:11
  • Why does everyone associate the common (and troublesome) implementation of Singleton with the pattern Singleton? One is almost always bad, the other not. Feb 17, 2011 at 20:11
  • 2
    @qes > Singleton pose important implementation issues (especially with threading). This already is a bad point. But, you'll also find out that singleton is a pattern about how the class is sued, and not how it works. How the class is used should be handled by the code using the class, so Singleton is a breakage of separation of concerns.
    – deadalnix
    Mar 13, 2012 at 13:38
7

If you know patterns, that are often misused or even difficult to use, they would also fit as an answer.

Following the MVVM pattern for WPF too strictly, as indicated for example by this question. Some people try to follow the guideline that no code should be put in the code behind way too strictly and come up with all kinds of exotic hacks.

And ofcourse, MVVM is difficult as hell, and just not worth it for small short term projects.

Dr. WPF did an ironic post about it in his article M-V-poo.

2
  • @Akku: You should ofcourse know how to use it, so you can decide whether it's suitable for your project. So yes, it is essential for WPF development, and very useful. Feb 17, 2011 at 14:24
  • One of the issues is that people misunderstand the MVVM pattern. It's not "difficult as hell." People make it that way by thinking that all other patterns such as Command Pattern and Mediator Pattern are part of it. On its own, MVVM is one of the simplest patterns, in my opinion. I do, agree, that following anything to the t is just silly.
    – B.K.
    Oct 22, 2015 at 15:22
5

Some of the patterns in the GOF book are C++ - specific, in the sense they are less applicable in languages with reflection, e.g. the Prototype pattern is less significant in Java.

I consider the Interpreter pattern as a 'narrow' one. You have to have a general problem which is worth developing a general problem solver. It only works for special problems for which you can invent a language, define a grammar and write an interpreter. The problem instances should be representable as a sentence in the grammar. I don't think you come across such situations often.

1
  • 1
    most of GOF is only applicable to static class based OOP. stray ever so slightly from that kind of languages and the book becomes just an entertainment anecdote.
    – Javier
    Feb 17, 2011 at 12:03
5

The one i regret most often (though not most vehemently): When I should have just created a function but I implemented an OOP solution.

3
  • 1
    Why? What made you regret it? Please expand your answer and add your experience.
    – Walter
    Feb 17, 2011 at 15:46
  • Indeed, I think a class with local variables and clear methods is MUCH easier to reuse than a single 200 line function that can only be reapplied via copy paste and then doesn't only have one place to look ugly and uncomprehensive.
    – Akku
    Feb 18, 2011 at 6:40
  • 2
    KISS implies you make it a function first, then refactor to a class if needed.
    – Eva
    Mar 21, 2013 at 6:25
5

Factory. I've seen code implement it that only creates one type. That's completely useless code IMO. It doesn't help that many of the examples online are completely contrived. Pizza factory?

Perhaps the factory is easier to test because of dependency injection. But to add that code when you ain't gonna need it is pointless to me, and the test argument disappears when you can use mock frameworks like JMockit. The simpler you can make a program, the better. Factories only really make sense with larger numbers of types (by larger, I mean at least more than 2).

1
  • Yes, Pizza factory, thanks for Head First Design Pattern~
    – NingW
    Apr 4, 2019 at 6:44
2

Singleton

I agree with the others about Singleton. Not that you should never use them, just that it should be limited to very few cases. They are used as lazy globals a lot of the time.

Thread-safety is one issue with singletons. Exception handling is another - if the singleton fails to create properly - you don't always know if you can catch the error safely, particularly if it was one of those objects created "before main". And then there is the issue of cleaning up afterwards.

I tend to prefer to use one singleton and have all the other "wannabe" singletons "subscribe" to your one. My most common singleton use is "shout event" handling: you just "broadcast to the world" that an event has taken place and anyone listening that will handle the event does so. That way you decouple the events actually happening with what is listening to them. (Logging, signals, etc.)

Visitor

The ugly thing I find about this, apart from the fact that developers can't think of meaningful names and just call methods visit(), is that it adds extensibility in one direction whilst removing it in another, i.e. it adds extra functionality but restricts the number of objects as your visitors need to know about all the object types it may visit.

It is possible, though messy, to allow the extension in both directions but this does not totally use the visitor pattern in its regular form. The most common application for this is printing objects: you have different ways to print objects and different objects that need to be printed. You should be able to extend this in both directions. (Printing means any kind of turning objects into a stream: storing in a file / writing to a console / GUI.. etc).

(Note: you should not confuse this with document-view architecture, which is a slightly different pattern).

1
  • 2
    Your solution uses the old it decouples things argument. In particular, you post an event and some other guy handles the event and logs it. That's a good thing, because everyone is decoupled! WRONG! I used to do that, what a royal pain it became. I realized that if I want something to be logged, I want to explicitly say log this exact thing, right here, right now, in the code at the point that it occurred. Not have some other object figure out what should be logged, with possible other events interjected by other handlers, if it is even logged at all. It is nothing but convoluted overdesign.
    – Dunk
    Feb 17, 2011 at 16:28
2

I think the problem with some of the more complex patterns is that there are so many variations on them that they lose much of their value as a communication device.

The worst offender I can think of in this category is the MVC pattern. Even if we ignore MVP, there are so many variations in the roles of each of these items that you have to spend an hour in each new framework figuring out where the boundaries lie.

1
  • I also think that MVC should be used everywhere, but not be implemented the same way everywhere. And many people don't understand it. When I first wanted to use it, I made three classes named Model, View (a windows form) and Controller. It was a mess, as forms were not made for MVC.
    – Akku
    Feb 18, 2011 at 6:35
1

There are no bad patterns only bad people.

I'd much rather inherit easily readable code that does something clear but is a little verbose or not(queue evil villian music) re-usable(gasp!) than some mish mash of InheritAbstractTemplateFaucetSink<Kitchen>.

Re-usable code is great! Chances are you are not writing code that will be re-used or re-writing similiar logic for another application would take you less time than some insane attempt to re-use some other application's code.

For further reading crack open some of the C code in the sane implementations of the posix headers or the clibs and play spot the pattern. This code was written by some of the smartest and most dedicated programmers in the world. Do you know how many Abstract Factory Patterns you're going to see? ... NONE!. Even better chances are if you understand the other parts of whats going on, you'll find the logic very easy to understand and trace.

My point is this most of the "patterns" were not created to make code better they were created to sell books and modelling software. If you are good at programming you will probably eschew most of these and write clear,concise, and cleverly designed code that solves your problem. When you have another problem you will write clear, concise, cleverly designed code to solve that problem. If your goal is to write less code than I would think your not cut out to be a programmer. I love writing code and want to write it as much as possible. When I re-write something I've already written I do it tens times as fast and get to get rid of all the things I wasn't happy with the first time I did. As a bonus I get to do it with none of the limitations of the first problem set because its a new problem(I probably have 15 scripts in 5 different languages that start tomcat floating about).

With that I will leave you with probably the best(relevant) quote in computer science.

"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult."

  • Tony Hoare(inventor of the quicksort, father of modern OS design, creator of Hoare logic, and Turing award recipient)
0

I definitely agree that there is a time for most patterns, and that you can abuse many patterns. I know the one I've abused the most in the past is the Abstract Template pattern. Taken to it's full extent it is known as ASP.NET webforms.

Not the answer you're looking for? Browse other questions tagged or ask your own question.