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.

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise.
If this question can be reworded to fit the rules in the help center, please edit the question.

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.
–
Theodore NorvellJun 17 '14 at 17:14

12 Answers
12

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.

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 KFeb 17 '11 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.
–
qesFeb 17 '11 at 20:10

5

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.
–
Les HazlewoodSep 21 '13 at 4:15

There are numerous fundamental flaws in the singleton pattern, most are well illustrated in this article by Steve Yegge - Singleton Considered Stupid
–
SlomojoFeb 17 '11 at 9:48

Slomojo: Nice article. I'm going to call it 'simpleton pattern' from now on :-)
–
rmxFeb 17 '11 at 10:10

1

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.
–
DunkFeb 17 '11 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.
–
qesFeb 17 '11 at 20:11

1

@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.
–
deadalnixMar 13 '12 at 13:38

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.

Absolutely. Patterns are not good nor evil, they are well-applied or misapplied.
–
user4051Feb 17 '11 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 KFeb 17 '11 at 19:50

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.

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.

@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.
–
Steven JeurisFeb 17 '11 at 14:24

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.

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.
–
AkkuFeb 18 '11 at 6:40

KISS implies you make it a function first, then refactor to a class if needed.
–
EvaMar 21 '13 at 6:25

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).

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).

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.
–
DunkFeb 17 '11 at 16:28

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.

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.
–
AkkuFeb 18 '11 at 6:35

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.

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)