It is generally acknowledged that the successful development of a software product essentially depends on the process. Although important, technical considerations often play a minor role in producing successful software. The development process rationalizes the series of actions and decisions to make the end product meet the initial goals.
This book aims to guide the reader through the main concepts of object orientation, including encapsulation, inheritance, and composition. The book begins with elementary definitions of objects and classes before moving on to advanced topics such as design guidelines, serialization, persistence, and web services.
The book is written in a pleasant fashion, making it easy to read. Most topics are illustrated with comprehensible scholarly examples.
Having said that, I admit that I found the book rather disappointing. There are three main reasons for this. First, it is written as if it were a transcript of hand-waving discussions. For example, a class is a factory of objects, and not really a blueprint as the author states (page 17). The central notion of polymorphism (page 28) is unfortunately blurred into contrived examples without making the point clear. Polymorphism refers to the ability of a variable to hold object references that share a common interface. The circle, shape, and stack examples illustrate this point, but the section fails to present polymorphism in a crystal-clear fashion. On page 145, which is about abstract class, the author states: “An abstract class is a class that contains one or more methods that do not have any implementation provided.” This is inexact. An abstract class is a class that is considered incomplete by its author. As a consequence, an abstract class may indeed have implementations for all its methods (as was the case in an early version of JUnit, for example).
The second weak point of the book is its incompleteness. Whereas the benefits of inheritance and the use of frameworks are discussed at length, method overriding and super calls are not even mentioned. How can a framework be reasonably designed without mentioning these points? Unit testing is also not mentioned. It is widely acknowledged that clear design principles are hard to stick to without unit testing.
The third and maybe weakest point is the lack of a clear takeaway. The book offers many interesting discussions and examples about the relevance of thinking first about encapsulation, responsibilities, and promoting clear and efficient object design. However, these topics have been presented in many other books. The book does not specify any good and easy-to-apply techniques for promoting object-oriented design, which is still the source of many debates.
Although the author has made significant and lengthy efforts in this book (already in its 4th edition, covering nontrivial topics), I would not consider it an absolute must-read if one were looking for ways to become a better programmer.