Design patterns are generic, reusable solutions to recurring problems. A hallmark of object-oriented programming, they provide a common vocabulary that many in the Java and Ruby worlds are familiar with.
On the other hand, patterns can be a source of verbosity and boilerplate. To this point, Paul Graham observed that the existence and use of design patterns in a language are indicative of a weakness in the language itself, rather than a consequence of solving the problem at hand:
When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I’m using abstractions that aren’t powerful enough…
—Paul Graham, http://www.paulgraham.com/icad.html
Graham was hardly the first to make this observation; Peter Norvig demonstrated some time ago (http://www.norvig.com/design-patterns/) that Lisps in particular either simplify or make invisible most design patterns. Clojure continues this tradition: thanks to powerful constructs like first-class functions, dynamic typing, and immutable values, many of the most common design patterns evaporate into thin air. And, with macros, Clojure gives you the tools you need to avoid creating boilerplate of your own.
Examples of Clojure code subsuming common design patterns are scattered throughout this book:
Listener, Observer. A victim of first-class functions and dynamic typing, these are ...