||New Reviews| |Software Methodologies| |Popular Science| |AI/Machine Learning| |Programming| |Java| |Linux/Open Source| |XML| |Software Tools| |Other| |Web| |Tutorials| |All By Date| |All By Title| |Resources| |About||
Keywords: Java, design patterns, object oriented design
Title: Holub On Patterns
Author: Allen Holub
Verdict: Highly recommended
Unlike the majority of books on design patterns in software, this one is not structured around a series of stand-alone patterns that exist in splendid isolation. Where most patterns books are catalogues of varying degrees of complexity, this one is heavily code-centric and seeks to show patterns as they exist in the wild. This makes for a much more complex and demanding read but it's necessary because the real world is much messier than the relatively simplistic world that emerges from the relatively simple examples in many design patterns texts. There's no doubt that there's a big gap between an intellectual understanding of patterns and being able to recognise when and where to use them in your own code. This is the gap that Allen Holub aims to bridge with this book.
The book opens with a couple of chapters that set the tone: opinionated, technically demanding and not afraid to massacre a few sacred cows. It's worth pointing out up front that this is not a book for a beginning Java programmer. The code samples and the discussion demand both a sound knowledge of Java and also a familiarity with the underlying object-oriented principles which it implements. You need to understand the difference between implements and extends, for example.
In the first chapter Holub lays it on the line with a certain glee. Take his argument that getters/setters are inherently evil. It's a great tag line, pithily controversial, but he puts forward a well-argued case that accessors/mutators make for tightly coupled and therefore fragile code. It's the same with his argument that implementation inheritance leads to 'fragile base class' issues that also makes for tight coupling and therefore increase maintenance overhead. Holub's argument is that objects are best seen not as containers for code and data but as being defined by their responsibilities. And in this case inheritance using interfaces loosens coupling, improves maintainability and focuses on the public face of a class rather than what it contains and how it implements its responsibilities.
As well as making strong arguments for a series of controversial views, the first two chapters also introduce a range of design patterns straight out of the catalogue (i.e. the patterns first described by the Gang of Four). Discussion of these patterns is structured very much around realistic examples along with copious Java source code. In all cases the examples are set in context, the code doesn't have the feel of toy code which is contrived to prove a point. Furthermore, Holub is very good at pointing to places in the core Java APIs that make use of particular patterns as well.
By the end of the first two chapters the author has made a series of points about object oriented design and how these fit with patterns. While the tone is firm Holub is at pains to show that he is not dogmatic. While getters/setters may or may not be evil, he is at pains to show that they have a cost and that developers need to be aware of these costs. Use them in your code where it makes sense, but be aware of the implications and certainly do not add them automatically to your classes by default.
The next two chapters provide the bulk of the book (around 260 pages of a total of around 400). The first is an implementation of Conway's Game of Life. Here the code is probably more convoluted then you'd probably want, but it provides a good way of showing how patterns are used in a fairly substantial project. And it illustrates how a UML class diagram and a map of patterns do not coincide. It's messy. On the other hand it does show how thinking in patterns can simplify a design, even if it's hard to come up with a simple design in the first place. The next example - implementing an embedded SQL interpreter - is even bigger, though it has the virtue of being production code.
These two examples are more than enough to exercise the majority of the classic GoF design patterns, including creational, structural and behavioural patterns. The emphasis on code makes this heavy going at times, and it's there to illustrate how patterns are used, so even if you skip the pages of listings at times it's there when you want to go back and revisit if and when you need to use a pattern in your own code.
The book closes with a catalogue of sorts, a pattern quick reference. This is a useful addition to the book rather than a convenient space filler. It's a nice reference to have around, and again each pattern has code and pointers to the Java APIs where appropriate.
Whether you agree with everything that Holub has to say or not, there's no denying that this is a valuable and thought-provoking book. Design patterns are really about making the best use of object orientation, and this book provides plenty of good advice independent of particular patterns. Reading this will change the way you look at your code, at the very least.