My Review of Practical Object-Oriented Design in Ruby

Practical Object-Oriented Design in Ruby is the best book about Object-Oriented Design I've ever read. I finished reading this book in January, but I spent several hours in April again to read it again. It's the first book (except textbooks) I have read for more than once. I highly recommand that everyone who wants to learn Object-Oriented Programming or Object-Oriented Design to read this book.

Here is my summary for it and some random thoughts.


This is a really well-structured book, started from how to write a good class to how to make different classes working together nicely. It's like a great code repo: every chapter serves one and only one single purpose, and all of them are combined together into a working whole piece. No wonder why people say that writing good software is like writing a book. You can know if one is a good developer by reading his/her book.

Basically, Sendi Metz taught us how to write well-structured software by taking a bottom-up approach:

Object-Oriented Design
An introduction to OOD.
  • Why do we need to do OOD?
  • What is OOD?
  • When to do OOD?
  • How to do OOD?
Designing Classes with a Single Responsibility
This chapter is about how to code a well-designed, easy-to-change class.
Managing Dependencies
How to manage dependencies for a class.
Creating Flexible Interfaces
How to design interfaces for a class.
Reducing Costs with Duck Typing
How to recognize and exploit duck types to make the application more flexible and easier to change.
Acquiring Behavior Through Inheritance
How to properly use inheritance or how to build a technically sound inheritance hirarchy.
Sharing Role Behavior with Modules
How to use an alternative inheritance way (modules) to share a role.
Combining Objects with Composition
How to use composition to model a has-a relationship.
Designing Cost-Effective Tests
How to write cost-effective tests.

Some random thoughts

OOD is truly an old topic in the computer science world. I'm surprised how people in 1980s had explained it well1.

But it's really hard to design our code well using OO techniques. Because our world is changing so fast, so do the requirements to our software. Making a good design requires us to know all the theories and use our existing experiences as much as possible.

When we finish the implementation, our experiences grow, which means we might get a better design in our mind after the whole design process. But due to the cost of switching implementations, we might not be able to switch to the new design. To prevent this kind of things happening, we need to keep things simple2, only simple things are easy to read, understand and change.

Design, implement, refactor. This loop reminds me of the TDD loop: red, green, refactor.

Making a test fail is the design stage. We cannot write a test if we don't have a design in our mind.
Making a red test pass is the implementation stage.

This is the most important stage through the whole TDD loop in my opinion. Like our customers, who can't define the software until they see it, we as software developers can hardly see the whole picture before we finish the whole thing. I usually find that I have a new, better design after the implementation finished. Here is where refactor comes in and saves the world.

But refactor is also a really big topic. I also wrote a review of Refactor by Martin Fowler.