06 October 2009

Smart Programmers Who Don't Get Patterns

I've been recently struck by the relatively large amount of ignorance about software design patterns amongst the pundits and seemingly intelligent "thought leaders" of the sofware development blogosphere. Actually it's not all that recent.

Sure, I expect newbies and unscreened job applicants to fail to understand the point of design patterns, but to me they've always been one of the things all good developers should understand.

First, I don't think the problem is the definition. I'm not squabbling about this. People get this mostly right. A design pattern is a form of solution to a known problem. They originate from Christopher Alexander's work in Architecture where examples include the "Ante Room" or "Roof Garden". The idea is that a pattern describes a general solution to an open range of problems. Architects might consider adding a "Roof Garden" when they are faced with forces and constraints in a design project where the Roof Garden can help achieve the design goals.

Thanks to the work of many OO pioneers, but most famously the Gang of Four via their seminal book, Design Patterns, the software world has adopted design patterns as a technique for storing and disseminating software design wisdom.

But why?

This is where many otherwise well-trained and intelligent software developers fall down. They think that the point of design patterns is component reuse. They think that, like building blocks, design patterns are prefab parts you can stick together, thereby doing less work or using less attention. And once this mistake is made, their rejection of this dumbing down of attentive design in place of convenience is understandable.

But they have missed the point.

The whole point of design patterns is to enable communication about design. Design patterns are an attempt to standardise a vocabulary for solutions. Design is frequently a collaborative effort, and even when it's not, a design concept often needs to be communicated either verbally or in written form. Learning about system design also relies on a standardised language.

So a design pattern usually has a kind of specification which includes a stable name and possible aliases, description and suitable use situations. Developers who have used this pattern can then use the name instead of some long-winded boxes-and-lines session at the whiteboard.

Now for some examples of seemingly intelligent and experienced software developers speaking out against design patterns.

Some years ago Paul Graham and others argued that Design Patterns suggested a violation of the DRY principle and that they always indicated a smell that the program required refactoring to remove duplication or that the language was not powerful enough to factor out the duplication. While this could in theory be true, only Lisp developers are in danger of suggesting that their language is perfect, so for the rest of us (statistically speaking, everyone), perhaps there is enough complexity and subtlety in our domain that we find ourselves able to recognise solution forms that we can name and talk about, and yet not implement generically.

I take his point, but I think for most people it's a principled rather than a very practical one. The reality is that we live with imperfections in everything, so even if design patterns only exist to cope with this imperfection, then they will still have a seemingly permanent role.

The point that different languages have different patterns, some more than others, is well documented, and really orthogonal to the issue at hand - namely that design patterns are useful primarily for collaboration and communication. Even programming language designers use design patterns. All (impefect) programming languages, like all software, are knowingly designed to contain a subset of all possible features. Don't forget simplicity is a very valuable feature. Apparently Ralph Johnson, one of the Gang of Four, pointing this out did little to calm the hysteria on an argument that design patterns formed a list of language features that should be implemented.

Zed Shaw, Ruby on Rails agitator and apparent chronic self-congratulator warns developers in his keynote entitled "Why Keynotes Suck" which was (with what one must assume is deliberate irony) literally read off an irc channel:

"Stop using patterns. No really, quit using patterns, they aren't helping. I have evidence on that by the way, which is later"

I didn't catch the evidence but later he did say:

"Adapter, Bridge and Connector are the same"

And then

"Patterns suck, use algorithms."

The idea of patterns "not helping" conjures images of these dead zones in the code where there is a pattern just taking up space and not actually providing functionality. Should I go and delete all the patterns from my code? What would pattern-free code look like? Do they just suck because there are aliases? Plenty of algorithms have multiple names. What makes algorithms ok? Is Zed just trying to sound old school?

To be fair, during this talk his main point was to encourage individual thinking and not to follow advice blindly (including his own) but I do get the impression that his idea of patterns has come from the blind cookie-cutter adoption of patterns with small amounts of bad glue code holding the "architecture" together. We've all seen it.

A recent example is from a video interview with Stuart Halloway author of "Programming Clojure" and a series of articles about post-java jvm languages. When explaining the advantages of macros, Stuart basically repeats Paul Graham, saying,

"Languages that have macros don't really have design patterns".

Perhaps because he thinks a design pattern is when:

"I couldn't really figure out how to solve this in a resuable way, so whenever I hit this problem I copy and paste from somewhere else and tweak. So it's amazing that design patterns has put a positive spin on this copy and paste reuse of these blocks of code".

I'm not an expert on functional languages with macros, but Peter Norvig is. Even this mighty Lisp and AI guru identifies design patterns in such languages though he does say that 16 of 23 patterns are either invisible or simpler due to language features like macros, first class functions and multimethods. Stuart may be overstating it - I think what he is talking about is a more populist use of the canonical GOF design patterns and similar OO patterns.

The dread curse of this misunderstanding about patterns seems to have arisen from the usual cause of all technology's ills: marketing. I distinctly recall a Compuware salesman give a bone dry presentation to a local Java user group in about 2000 demonstrating how you could avoid programming almost completely by dragging and dropping patterns from a palette onto a ... thing on the screen. Clearly not targeted to a group of programmers so geeky that they want to get together after hours and talk about the joys of programming. Similarly books about something called "pattern oriented architecture" began to appear and patterns was something to put on the resume.

What these people need to understand is that design patterns will continue to be useful and to have a role because they are one level of abstraction above implementation. They are needed to explain solutions in terms of a programming language but they cannot be replaced by the language. They are softer than software.