I'd like to start with the following statement: this is one of the most valuable books on software engineering I've read to date. The rest of the review will hopefully explain why I think so.
The main idea of the book is that we can get lots of valuable information about our code, our architecture and our organization by mining the data in our version control systems. The reason is that these systems come closest to a log of how the code and architecture have evolved over the years. We can thus "replay" and filter this history to detect issues and pull some interesting metrics. For me, I sort of knew the data was there but lacked the guidance on how to make sense of that data. This book provides both - a way to mine the source control system (examples use Git) as well as advice on how to make this data useful.
The techniques to mine the source control data are presented in both a conceptual and practical way. I really liked that, as the conceptual description allows translating these techniques to other source control systems and the practical examples (with specific Git commands, ready to apply) allows to try these techniques out.
The guidance on how to interpret this data is what makes this book stand out. The content can be roughly split into three main questions that the book tries to answer:
1. How to discover the files, methods, and components where paying back technical debt brings the biggest return of investment?
2. Does my architecture support the way my system evolves and if not, how to make it so?
3. Does my organizational design make it easy to work with my system the way it is structured and if not, what can I do about it?
This book might at the first sight look like a "legacy code" book, but it very soon proves to be much more than that - for example, the second part not only shows how to detect suboptimal architectural decisions, it also discusses several architecture styles, their pros and cons and how to use data to determine whether a particular style is for you. I had lots of fun confronting the author's data-driven conclusions with Robert C. Martin's Clean Architecture, which I consider a more principle-based book. The author himself does a lot of such comparisons - putting the industry-accepted principles within the context of real data is what shines throughout Software Design X-Rays. That is also why you should not expect a prescriptive approach here. The book does not describe any "silver bullets". Rather, it discusses various options, nuances and contexts. Also, it respects software development as an evolutionary process and does not only describe a desired outcome of software engineering effort (e.g. how a good design should look like), but also situations where the bad design or organizational decisions have taken their toll and where sometimes counter-intuitive measures may provide a better outcome. I saw a lot of this in the third part where Adam suggests that, instead of fighting the way our code is structured with idealized teams breakdown, it might be sometimes more optimal to organize teams around the structure of the code, no matter how broken it is. As mentioned, the content goes way above just "legacy code" and if I could change the subtitle of the book, I would probably name it "Modern software engineering through the lens of data". You will not only learn from this book how to approach technical cleanups, you will also get valuable lessons from evolution of existing, real-life projects. The examples use publicly available pieces of code written in several different programming languages as well as some polyglot projects.
Most of the techniques presented in the book are surprisingly simple, which makes them even more powerful as when reading through the book, I could not reject the urge to start implementing some of them myself (and I mostly did). I had lots of fun analyzing my pet projects, both with my own, half-baked implementations and using the CodeScene tool that Adam has created with his team and which is free for limited use (but only with public Git repositories). Indeed, if you are seriously planning to dig into the contents of the book, you'd better familiarize with this tool as most of the examples and illustrations use it.
Another plus for me is that the content is presented in a lightweight form, with lots of illustrations and examples and occasional dose of industry humor. This is not an academic book, and even though it talks a lot about metrics, you can hardly find a math formula inside. All of this made the book an easy read for me.
Before I finish this review, several words of warning. First of all, this is the second book by Adam Tornhill on the topic of behavioral code evolution, succeeding Your Code as a Crime Scene. I did not read that book, but if you did, there might be some content here that you already know. Second, this is probably not a book for novice programmers as it is accurately presented on the cover. You need to at least have some experience with the problems author is addressing to understand why they are relevant and to interpret the results of the techniques presented in the book.
Overall, I wholeheartedly recommend this book. It shifted and expanded my views on code, design, architecture and software organizations and I cannot help but look at these topics now from the perspective of product evolution they are meant to support.