C# Design Patterns – Choosing the Right One

cdesign-patterns

I've always recognized the importance of utilizing design patterns. I'm curious as to how other developers go about choosing the most appropriate one. Do you use a series of characteristics (like a flowchart) to help you decide?

For example:

If objects are related, but we do not want to specify concrete class, consider Abstract

When instantiation is left to derived classes, consider Factory

Need to access elements of an aggregate object sequentially, try Iterator

or something similar?

Best Answer

A key misconception in today's coding world is that patterns are building blocks. You take an AbstractFactory here and a Flyweight there and maybe a Singleton over there and connect them together with XML and presto, you've got a working application.

They're not.

Hmm, that wasn't big enough.

Patterns are not building blocks

That's better.

A pattern is something that you use when you find that you've got a problem - you need some flexibility that the pattern provides, or that you've stumbled across when you are making a little language in the config file and you say "wait a moment, stop, this is its own interpreter that I'm writing — this is a known and solved problem, use an Interpreter pattern."

But note there, that it's something that you discover in your code, not something you start out with. The creators of Java didn't say "Oh, we'll put a Flyweight in the Integer" at the start, but rather realized a performance issue that could be solved by a flyweight.

And thus, there's no "flow chart" that you use to find the right pattern. The pattern is a solution to a specific type of problem that has been encountered again and again and the key parts of it distilled into a Pattern.

Starting out with the Pattern is like having a solution and looking for a problem. This is a bad thing: it leads to over engineering and ultimately inflexibility in design.

As you are writing code, when you realize that you're writing a Factory, you can say "ah ha! that's a factory I'm about to write" and use your knowledge of knowing the Factory pattern to rapidly write the next bit of code without trying to rediscover the Factory pattern. But you don't start out with "I've got a class here, I'll write a factory for it so that it can be flexible" — because it won't.

Here's an excerpt from an interview with Erich Gamma (of Gamma, Helm, Johnson, and Vissides): How to Use Design Patterns:

Trying to use all the patterns is a bad thing, because you will end up with synthetic designs—speculative designs that have flexibility that no one needs. These days software is too complex. We can't afford to speculate what else it should do. We need to really focus on what it needs. That's why I like refactoring to patterns. People should learn that when they have a particular kind of problem or code smell, as people call it these days, they can go to their patterns toolbox to find a solution.


The best help for the "what to use, when" is likely the Wikipedia page for software design pattern - the "Classification and list" section describes the category each pattern is in and what it does. There's no flowchart; the description there is probably the best you'll find as a short snippet for "what to use, when."

Note that you'll find different patterns in different areas of programming. Web design has its own set of patterns while JEE (not web design) has another set of patterns. The patterns for financial programming are completely different to those for stand alone application UI design.

So any attempt to list them all is inherently incomplete. You find one, figure out how to use it and then it eventually becomes second nature and you don't need to think about how or when to use it ever again (until someone asks you to explain it).