Tuesday, 3 April 2012

Design Patterns, The Emperor’s New Clothes and Catch 22

When writing this blog one of the things I do before I metaphorically put pen to paper is to verify what I’m going to write is correct and I usually do that by either checking a text book or looking on the Internet. Now, my last blog described the Strategy Pattern and, of course I double checked that I wasn’t presenting the Bridge Pattern which has a UML diagram that’s very similarl to Strategy. In doing this it occurred to me that the Gang Of Four (GOF) design patterns have been around a few years (again I double checked Design Patterns: Elements of ReusableObject-Oriented Software by the Gang of Four: Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides was first published in 1994) and that over the years these ideas have been copied and republished in numerous blogs and on a multitude of web sites. It then occurred to me that if these patterns have been around for such a long time, then why is it that they aren’t that well known and more widely used on a daily basis?

The patterns are ‘famous’ and virtually everyone who comes across them thinks that they are a cool idea. So, although I like the GOF Design Patterns I thought that it would be a good idea to figure out if there are any problems with using them. Are they as good as people think? Or is it just that developer's think they’re cool: a case of The Emperor’s New Clothes?

To try to answer this I thought I’d find out whether other people thought that there were any problems with Design Patterns. Naturally, I asked Google for some help and it came up with a few pretty academic / theoretical reasons as to why design patterns are bad.

The first reason I found was the idea that design patterns arise because of failings or limitations within a programming language1. This is probably true, as Jeff Atwood points out in his blog Are Design Patterns How Languages Evolve? many language features that we take for granted started out as patterns in assembler or C. I have to wonder if this is really an issue? Languages can be improved and, although they only improve a snail’s pace, patterns are used to fill the gaps. An example here would be the introduction of Java’s for each loop that replaces the use of the unwieldy iterator pattern:

  public double calcTotalCost() {

   
double total = 0.0;
   
for (Item item : items) {
     
total += item.getPrice();
   
}

   
return total;
 
}

Another argument I found against GOF design patterns is that some patterns can lead to code for which it’s hard to write unit tests - the prime example quoted was the Singleton Pattern as it’s very hard to mock a static singleton, which is true: see my blogs on using PowerMock. On the other hand some patterns make testing easier. My last blog covered the Strategy Pattern, which allows you to change the behaviour of your objects by injecting strategy objects. If you can inject real strategy objects, then you can easily inject mock ones for testing.

The third reason I found against the use of design patterns is was because the idea of a design pattern is an attempt to standardize what are already accepted best practices, it will often result in the unnecessary duplication of code where there is almost always a more efficient solution using a well-factored implementation rather than a "just barely good enough" design pattern.2

This is something I disagree with as to me it suggests that design patterns are a mistake because they’re used inappropriately and this brings me onto one of my own ideas on the limitations design patterns.

I, as a hard working itinerant programmer, think that if there are any problems with design patterns, then they’re generally more practical in nature. You have to remember that there are 22 GOF patterns divided into three categories: creational, structural and behavioural. To use these patterns effectively you have to be able to remember them all, and I don’t just mean that have to remember their names, you also have to remember what they do.

Consider this little test: without referring to the internet, books, etc. from memory:
1) How many of the 22 GOF patterns can you name?
2) How many of those you named can you draw the UML diagram for?
3) How many of those you named can you implement without referring to the documentation?

Compare your answers with the number of years experience you have and consider how many years it’s taken you to get as far as you did...

...the point being that it’s not an easy feat remembering all the patterns and then keeping them fresh in your memory ready to bring out a moments notice.

Having learnt a number of the patterns you also need to spot when and where you use them: there is that point in your coding day when you you're at at certain place in your logical thinking and you say to yourself: "yes I need the Observer pattern" or “ah-ha the Decorator pattern fits in very nicely here” …the point being that spotting when it’s appropriate to apply a pattern is probably more difficult than learning them.

I believe that most people agree in with the idea that you should use the simplest method possible to get the job done, but most patterns are quite complex, and complex to the point that you don’t really want patterns unnecessarily cropping up in your code. Jeff Atwood’s Coding Horror blog on O’Reilly’s Head First Design Patterns sums this up nicely where he says that allowing inexperienced developers to experiment with patterns is “about as safe as encouraging them to ‘experiment’ with a gas-powered chainsaw”. And this is where the logic loops back on itself: you should use the simplest approach possible to solve your problem, Design Patterns are complex, so they won’t be used very often. In not using Design Patterns you’ll never get chance to learn them. If you don’t learn them, then when using a Design Pattern is the simplest approach to your problem, you won’t know how to use it. Is this ‘Catch 22’?

Lastly, I was going to point out that the GOF patterns are used all over the Java SDK, but someone’s already beaten me to that idea and so if you’re interested I suggest that you consult Stack Overflow.

Although Design Patterns: Elements of ReusableObject-Oriented Software is the definitive and original text, I personally prefer Head First Design Patterns by the other gang of four: Eric Freeman, Elisabeth Robson, Bert Bates and Kathy Sierra as I find it much more readable, plus the examples are in Java and not C++, but I do agree with Jeff Atwood’s analysis of the book.


1Links to patterns as a failing of the Language are:
2See SourceMaking

1 comment:

Adam Perry said...

I've often thought that besides the pros/cons you listed, one of the most valuable things these patterns offer is vocabulary. They give something a name.

When a team are working on designing a project they can talk about these patterns.

If you happen to have forgotten them you can refer to a cheat sheet/book/the web.

Being able to say "a chain of command would work well here..." is a lot quicker than describing what a particular pattern is...