Design Patterns in Ruby
I've been lucky enough to read a string of good Ruby books lately and the latest in that line is Design Patterns in Ruby. This book attempts to modernize the software design patterns by showing how these patterns can be applied in a language as dynamic as Ruby. Despite a couple of minor missteps along the way, the book definitely delivers on this goal.
Design Patterns in Ruby begins with a couple of introductory chapters introducing both the concepts behind reusable software patterns and the Ruby programming language. After that, the main section of the book has 13 chapters that walk through 14 of the patterns first introduced in the famous "Gang of Four" book that began the design patterns movement. The author then introduces three new patterns he feels have grown out of day to day Ruby usage. Finally the book closes with a short conclusion and two appendices on installing Ruby and other sources of information.
Most of that content is exactly what I wanted to find in this book, but you're going to have to tolerate a diversion about a pet peeve of mine that is strangely common in Ruby books. This is really, really important, so listen up: you can't teach Ruby in 30 pages. Period. I can hear all on the "But…" replies forming out there now… No buts. You can't. Trust me. Not even if the person is already an experienced programmer. It just can't be done. Authors and publishers need to come to terms with that and move on. Its just fine to say, "This is not a beginning Ruby book." We even prefer that, because we know when we are ready to read it and we don't have to skip that useless 30 page chapter when we do. Please, stop including introductory Ruby chapters in every book.
My rant aside, all of the other content in the book is exactly what you want to have in a title like this. Those familiar with the original work on design patterns will note from my earlier counts that this book does not include all of the patterns in the previous work. That's actually a plus, I think. The author hits the highlights for sure and leaves out some patterns that just aren't that common or are so trivial as to be almost automatic in Ruby. I was a little surprised to see Interpreter on the list of included patterns, thinking that it doesn't come up all that often, but the author won me over with a well presented case about it being an under-appreciated pattern. I do wish the State pattern had been included though. I run into it often enough in the wild and it's ripe ground for some Ruby tailored approaches.
For the traditional patterns that are covered, each chapter includes some description of the situations the pattern is suited for, UML diagrams of how the pattern looks when implemented, a traditional implementation written in Ruby, a look at how Ruby programmers tend to twist the pattern using some of Ruby's more dynamic features, some warnings about where you can go wrong with the pattern, and some examples from famous Ruby projects that use the pattern. The traditional implementations and the Ruby twists are the heart of each chapter and they prove to be the real one-two punch that makes the book stand out. This is a great way to transition your thinking from static object oriented solutions to the fully dynamic world Ruby lives in. Beyond that, it ends up being a great guide to all of Ruby's dynamic features since it doesn't just explain them but it also shows how and why you are likely to use them. This is what makes the book a must read for all Rubyists.
The three new Ruby patterns are a welcome addition as well. Again, these focus on Ruby's highly dynamic nature and how that can be used to simplify common problems we encounter in software design. This feels right at home with the rest of the material in the book. The new patterns are: Domain-Specific Languages, Meta-programming, and Convention Over Configuration.
The presentation of the content is another mostly good aspect of the title. The author's prose has a very conversational tone that's easy to enjoy and learn from. He often includes little anecdotes to ease you into the material of a new chapter. All of the code examples are a good fit. Most of the code is pretty basic, but it's always clear and shows the point well. A few of the later examples get a bit more involved, but they are really neat things to show.
The downside of the code is the error ratio. There are just quite a few technical errors in the book, either in the code itself or in the text discussing the code. I didn't run all of the example provided and I feel pretty comfortable saying I spotted an average of two technical errors per chapter. I wish the count could have been a bit less than that. For the most part, these errors don't get in the way of understanding what the author is trying to show. However, this is going to make the road a little bumpier for someone new to the material who needs to play with the examples to understand it well.
Before I wrap this up, I do want to say that I like hard back books. This title looks great on the shelf and should stand up to some abuse as it gets used as a reference to look up patterns over and over again. Maybe I'm in the minority, but I would like to see more hardback programming books even if they cost a small premium.
The final verdict is that Design Pattern in Ruby is another great Ruby book that we all need to take the time to browse through. If you're a programmer, you need to become familiar with design patterns and even if you are well schooled in the patterns this book's unique dynamic favorable approach is sure to get you examining them in a new light.