General Description
A 353-page book that's hard to call a complete book and is rather a supplement to the corresponding refactoring course. The reading level is easy. There's very little code, with examples built more as abstractions using flowcharts and diagrams. The first part of the book also contains images that are thematically well-selected and complement the content.
Brief Overview
The first part of the book is devoted to what the author calls "code smells." Essentially, these are signs that it's time to refactor certain code. The signs are grouped into different categories, for example, the first one is called "Bloaters" and includes such examples as large methods, large classes, long parameter lists, and similar things. There are quite a few other groups as well, such as "Violating Design Principles," "Working with Inheritance," "Temporary Variables," and many others.
The second part is dedicated to slightly more practical ways to solve the problems described in the first part. For example, what approaches to apply when classes or methods are large, how to split them, how to extract code, and replace all old occurrences with new code. By the way, all the practices here are also grouped into different categories, and quite a few have been collected.
Opinion
At the time of reading this book, I had already been programming professionally for over 10 years, not to mention the pile of years in college and university, so honestly, I don't really remember coming across any advice that would have been new to me. That's why I didn't take notes for this book. Nevertheless, it would be beneficial for beginner programmers to familiarize themselves with the book, plus it reads very quickly.
The entire book is mainly about OOP, and there isn't much information about functional programming. Overall, this is neither good nor bad, just a statement of fact. Of course, there were examples with which I would hardly agree, but this is all a matter of taste. Moreover, in different programming languages, coding styles and design patterns may slightly differ, so the author tried to choose some middle-universal position and stick to it. Often you can come across examples where in one refactoring we first do some action (extract a separate class where logically required), but in another example, on the contrary, we merge classes and simplify the hierarchy. Thus, the author emphasizes that each situation is unique and certain patterns must be applied depending on the situation, not rigidly.