Refactoring for Software Design Smells: Managing Technical Debt by Girish Suryanarayana, Ganesh Samarthyam, Tushar Sharma
Publisher: Morgan Kaufmann
I'm probably ridiculously biased, but there seems to be an increasing interest in legacy code. This is an important trend. We programmers spend the majority of our time on modifications and improvements to existing code. And we want to make sure it's time well invested. Refactoring for Software Design Smells fits right in that spot.
Refactoring for Software Design Smells starts with a brief introduction to technical debt and its relation to design smells. Design smells, as defined in this book, are an indicator of a potential design problem. Note that the smell isn't necessarily the problem itself. Rather, a design smell hints at a deeper problem. The design smells in our code are usually quite obvious. They get in the way of the modifications we want to make to the code, they hinder our ability to understand the program and they obscure the problem the code tries to solve. The hard part isn't to spot the smell - you'll inevitably run into it - but to identify the underlaying design problem. Once that root cause is understood, we can start to refactor towards a better design. And that's where this book comes in.
After the introductory prose, Refactoring for Software Design Smell dives into a catalog of design smells that makes up the bulk of the book. The catalog is organized around Grady Booch's four fundamental design principles (abstraction, encapsulation, modularization, and hierarchy). The design smells themselves are described in a strict format (like patterns). We get a name for each smell, rationale and cause, some examples and finally a discussion on suggested refactorings. This template for design smells serve the book well. I consider this book a reference. You want to read the introductory prose and the closing chapters, but you probably shouldn't read the catalog cover to cover. It makes more sense to glimpse through the material, familiarize yourself with the format, and look-up the different smells as you encounter them in real life.
There are several things I like with this book. First of all, the book covers an important gap in the existing literature. I also love that the examples are smells from real-world codebases (often from the JDK). Those examples help motivate the need for improvement as well as indicating the complexity of refactoring code that has grown over years and even decades. The authors also introduce short anecdotes as sidebars. That's a great way to make the text more accessible; Reading a strict template-based text isn't too entertaining, so we need the anecdotes to lighten-up the content. We developers love software war stories and the authors have plenty of them.
Refactoring for Software Design Smells is a solid work and I didn't really find any weaknesses. Sure, it's a book that focuses on object-oriented design in statically typed languages. These days I do most of my coding in Clojure, which is in a very different design space. We obviously have design smells in Clojure code too and there is a certain overlap with the smells captured in this book (in particular around modularization). But the majority of the material won't apply to you if you're into a different programming paradigm than mainstream OO.
As I read the book, it struck me how subjective software development still is. We like to think of programming as much more disciplined than it actually is. Yet many design choices depend on background and context. Let's take code duplication as an example since the authors frequently use that in their rationale for a smell. We programmers are conditioned to despise copy-paste code. Yet there's always a trade-off when we refactor two representations into a shared abstraction. Now context comes into play. Let's say that the original representations modeled different aspects of a problem even though the initial code is identical. That would mean they got different reasons to change. When that happens, your abstraction will break down in a heavy rain of control flags and boolean parameters. I'd argue that's worse than the original duplication. I'm well aware that such context-dependent trade-offs are hard, if not impossible, to capture in a book on general refactoring techniques. However, I'd love to see that happen.
To summarize, Refactoring for Software Design Smells is a valuable catalog of potential problems that you're likely to experience in all large-scale systems. It's also a book that does a good job at teaching fundamental object-oriented principles. This is a highly recommended read for Java and C# programmers.
Reviewed March 2016