99 Bottles of OOP by Sandi Metz and Katrina Owen is a hands-on programming guide that uses the deceptively simple problem of generating the lyrics to “99 Bottles of Beer on the Wall” as a vehicle for teaching principled object-oriented design. Rather than presenting abstract theory, the authors walk through a concrete coding exercise step by step, showing how to recognize bad code, refactor it incrementally, and arrive at a clean, flexible design. The book is written in a direct, conversational tone that feels like pair programming with two experienced practitioners, and it is aimed at developers who already know the basics of a language but want to level up their design instincts.
The central argument of the book is that good object-oriented design is not achieved by applying patterns up front but by listening to the code and responding to the pressures of change. The authors introduce the concept of “shameless green” — the idea that your first goal should be passing tests with the simplest, most obvious code possible, even if it feels naïve or repetitive. Only once the code is working and you feel the pull of a new requirement should you begin to refactor toward abstraction. This discipline prevents over-engineering and keeps the cost of change manageable. The book’s examples are in Ruby, but the principles apply broadly across object-oriented languages, and later editions added versions in JavaScript and other languages.
The authors are especially effective at teaching the mechanics of safe refactoring. They demonstrate how to make small, reversible transformations guided by tests, using heuristics like “make the change easy, then make the easy change.” Throughout the book they introduce a lightweight rubric called Metrics (drawing on tools like Flog and Reek) and the idea of code smells to give readers objective criteria for evaluating their own code, moving design judgment away from pure intuition and toward something more learnable and communicable.
Key takeaways
-
Shameless green first. Write the simplest, most readable code that makes the tests pass before thinking about abstraction. Premature cleverness is a form of waste, and naïve duplication is often cheaper than the wrong abstraction.
-
The wrong abstraction is worse than duplication. The book popularizes the idea (also associated with Metz’s collaborator Sandi Metz’s other work and Katrina Owen’s essays) that duplicating code is preferable to introducing an incorrect abstraction, because duplication is easy to remove once the right pattern becomes clear, while a bad abstraction entangles everything that touches it.
-
Let change pressure drive refactoring. Refactor when a new requirement reveals that the current structure resists change, not before. The need to add a feature is the correct signal that an abstraction is warranted.
-
Make the change easy, then make the easy change. This two-step discipline — first restructure the code so the new feature fits naturally, then add the feature — keeps individual commits small and safe and dramatically reduces the risk of introducing bugs.
-
Name concepts, not implementations. The book places heavy emphasis on finding the right names for new classes and methods, arguing that a well-chosen name encapsulates a concept and makes the design’s intent legible to future readers (and future you).
-
Use objective metrics as a starting point. Tools that measure cyclomatic complexity, method length, and code smells give developers a shared vocabulary and a less subjective starting point for design conversations, even if the metrics are not the final word.
-
Small, incremental refactoring steps are safer and faster. By committing to tiny, test-backed transformations rather than large rewrites, developers can move quickly with confidence, and the discipline of small steps trains better design intuition over time.