Recently I’ve been reading a book called Design Patterns in Ruby by Russ Olsen and decided to post some quick reviews on its chapters, more specifically, on Ruby’s implementation of the common GoF design patterns. These reviews will be extremely short and technical, most of the times I’ll comment just a bit about the pattern and just write all the code down for it, so this will be more of a reference guide than a review itself, but if you don’t know anything about design patterns than I advise you to buy this book, which, like all Head First books, is a really friendly guide.

The book covers 13 out of the 23 original GoF patterns and adds on another 3 patterns that are exclusive for the Ruby language. Since I’ll be reviewing all of them, here’s the table of contents linking to each post containing the pattern:

    GoF patterns

  1. Template Method
  2. Strategy
  3. Observer
  4. Composite
  5. Iterator
  6. Command
  7. Adapter
  8. Proxy
  9. Decorator
  10. Singleton
  11. Factory & Abstract Factory
  12. Builder
    Ruby patterns

  1. Domain-Specific Languages (DSLs)
  2. Meta-programming
  3. Convention Over Configuration

As this is an introduction post I’ll point out the basic knowledge you’ll need to have at least a notion of, so here are some general topics:

  • Separate the things that change from those that stay the same: software is always changing, which means your code will also change as well. By decoupling the things that are less likely to change from what aren’t, you’ll be avoiding the need to change a whole bunch of code all the time, because you’ll have the specific chunks that you know you’ll need to mess with in the same place.
  • Program to an interface, not an implementation: be as abstract as possible when coding, this way you’ll have alot more code that is ‘less likely to change’ than code that’s ‘likely to change’. By programming to an interface (or abstraction) you’ll always be targeting a much more general field (interface) which is much more flexible to maintain than a low-level one (implementation), and your code will be much, much more decoupled.
  • Prefer composition over inheritance: despite being taught that inheritance is a blessing because you get to reuse a bunch of code from the superclass, it’s actually something we should avoid at most. When you extend a class with the use of inheritance, you’re tying up a knot with both of them that will cause alot of coupling to the point that if you need to mess with the superclass, you’ll probably end up needing to mess with all its subclasses too. By using composition we can still reuse code without that super bond, which is the desired effect most of the times, so instead of the object being a kind of something, we can say it has something.
  • Delegate, delegate, delegate: with the use of delegation we can avoid having “god” objects that just do way more than it’s supposed to and just pass any unrelated jobs to the real object that should handle it, which is, most of the time, being held as a reference. The combination of composition and delegation is a powerful and flexible alternative to inheritance, which you will see that we’ll be exploring alot throughout the patterns.

Of course that, aside from this basic (really basic) knowledge, you’ll need to know some Ruby to actually understand every chunk of code that’ll be posted. Also knowing some UML to understand the class diagrams (which help alot in understanding patterns) would be nice.

Anyway, hope you learn something!