Author: Sandi Metz
Audience: Any programmer interested in O-O design
Reviewer: Mike James
Surely we all know about object oriented-design by now? Not really, a lot of what we know needs to be recast to suit dynamic languages and agile methods.
Although this book is superficially about Ruby you can read it and learn a lot about object oriented design in other languages. This isn't your usual Gang-of-Four, inversion-of-control, patterns book. It doesn't just tell you the jargon and expect you to swallow it whole. It explains why you need to approach things in a particular way.
It also doesn't just go through the motions of object-oriented design that is suitable for strongly typed class based language and show how Ruby can be made to conform to the way "better" languages do the job. In other words it presents a theory of object-oriented design that is suited to dynamic languages.
You might think that this makes the book only suitable if you are interested in dynamic languages, and Ruby in particular, but even if you are a Java, C++ or C# programmer you will learn a lot about how things could be done. In fact I can think of a few such programmers that I'd like to force to read the book!
The book starts off with a look at the philosophy of object oriented methods. This is the only chapter you can skip, or better skim read, if you already know some or any methodology. Chapter 2, however, is where you really need to start reading everything. It is an essay on designing classes with single identifiable responsibilities. It uses an example of a bicycle gear calculator which runs through the whole book.
Chapter 3 is about dependencies. Most books at this point start with incomprehensible examples and rush straight into some inversion of control framework or dependency manager. In this case the difference is amazing. The ideas of dependency and the problems it causes are explained using clear examples. If you read the entire chapter carefully you can't help but end up understanding what previously might have been just a collection of jargon and references to IoC.
Next we move on to consider the role of interfaces - particularly important for weakly-typed languages. Then on to considering duck typing. This is one of the few, perhaps only, discussions of duck typing as part of an object methodology I've read. Most of it is fairly obvious to any practitioner, but is is nice to have it codified. I particularly liked the section "Conquering a Fear of Duck Typing".
Chapter 6 is a consideration of inheritance and you might think that this is a bit late in a book on object-oriented methods, but no it isn't. Using inheritance correctly is difficult and it is not often that we need to actually construct an inheritance hierarchy. Then on to roles and Ruby modules and finally, in Chapter 9, to designing cost-effective tests. This is a chapter that you should get any programmer who is overdoing design-based testing to read. It is practical and shows how to evaluate tests in terms of how useful they are.
Overall this is an excellent book. Its style is down to earth but you still get some of the academic ideas introduced on the way. The result is very readable.
If you are interested in building anything but the smallest system using Ruby then buy and read it cover to cover. If you aren't using Ruby, then still buy a copy and read it - the Ruby code is no barrier to understanding its general points.