This article is also available in Chinese.

I’ve had a few beginner programmers ask me how to go from being able to write some code to being able to write nice code. I have a few book recommendations to this end. These books are great for people who are just starting out, but they also taught me a good bit when I was a few years into my programming career. A lot of them are in different languages — C, Ruby, Java — so reading them can be a bit of a challenge. For the most part, though, the concepts translate cleanly into whatever any language, and developing your polyglot skills early is never a bad thing.

Practical Object-Oriented Design in Ruby

by Sandi Metz

Longtime readers know about about my partiality to Sandi Metz. I think she does some of the best work out there explaining simple concepts to smart people. Practical Object-Oriented Design in Ruby, or POODR, is no exception.

Using a simple example of bike repair, she shows explains object-oriented theory in tiny examples, slowing building them up from an object with one method on it, to a full implementation of Fowler’s Replace Condtional with Polymorphism pattern from Refactoring (which I’ll talk about it in a moment). The concepts in this book are not mindblowing, but they’re patiently explained, start slow, and build on each other perfectly.

Design Patterns

by Gamma, Helm, Johnson, and Vlissides

Colloquially known as Gang of Four, this book was published in 1994. It’s one of the first books that just lays out a list of commonly used design patterns, explains when and where they should be used, and shows examples of how to use them. Several of the books I’ll recommend are like this. Even though they look like textbooks, they’re worth reading straight through like a normal book. When the time comes to use one of these patterns, you’ll know which book and chapter to flip to to get the details you need.

Gang of Four was written for a world of desktop GUI applications, and this is made clear by some of the patterns. For example, the Command pattern is clearly useful for undoable menu commands. These kinds of actions are rarer on iOS and the web, so the pattern has fallen out of favor. Nevertheless, seeing the path from problem to solution has helps you come up with creative solutions to your own problems.

Patterns of Enterprise Application Architecture

by Martin Fowler

If Gang of Four was written in an age of GUI desktop apps, Patterns of Enterprise Application Architecture was written in an age of web services. While its title suggests that it’s extremely dry, I’ve found it to be a very useful collection of patterns. It reads as practically a cookbook for a framework like Ruby on Rails, so much so that I wouldn’t be surprised if DHH read this book before setting out to write Rails.

The patterns, having been written for the web, deal with forms, HTML, and databases. While the former two categories are interesting, the database patterns can be used when writing modern iOS apps. If you want to think about how an ORM like Core Data (or ActiveRecord) is written, this book is the place to start. For example, Core Data uses the Identity Map, Lazy Load, Metadata Mapping, and Query Object patterns. Like Gang of Four, we don’t need to use all these patterns in our day-to-day, but seeing how its authors solved their problems is enlightening.

Refactoring

by Martin Fowler

This book is also by Martin Fowler. It gives a precise definition for refactoring:

I’ve been asked, “Is refactoring just cleaning up code?” In a way the answer is yes, but I think refactoring goes further because it provides a technique for cleaning up code in a more efficient and controlled manner.

And describes how refactoring fits into the process of normal development:

When you use refactoring to develop software, you divide your time between two distinct activities: adding function and refactoring. When you add function, you shouldn’t be changing existing code; you are just adding new capabilities.

After the introductions and defintions, Fowler dives into a list of refactorings. He starts from simple ones, like Extract Method, and onto more complex ones like Introduce Null Object. Like with the previous two books, it pays to read this one straight through.

Domain-Driven Design

by Eric Evans

While the other books are mostly lists of patterns, this book follows a slightly more narrative arc. A developer works with a domain expert in shipping goods overseas to build an application to manage boat itineraries. In the process, you learn about how to model a domain from the initial research phases to the actual coding. This book taught me about value types two years before Swift and its value types were announced.

The made-up Socratric dialogues between Evans’s programmer and domain expert are helpful too. Some people think that in an ideal world, a product manager can sit in-between the developers and the stakeholders. In the real world, you (as the developer) are ultimately responsibilty for clearly expressing the abilities and limitations of the software, and this book shows what those conversations can and should look like.

How to think vs what to think

Each of these five books is valuable in a special way — not just for teaching you their contents, but also for meta lesson of teaching you how to think about the problems you face. They all follow a general structure: given this problem, here’s a solution. Connecting the problems to the solutions helps you see the thought process that leads to that solution, and ultimately helps you apply that process to other problems.