This review of Brandon Savage’s Practical Design Patterns in PHP will include my own opinions and impressions about both the book, and the aspect of self-publishing. Many thanks to Brandon for giving me a review copy.
Design patterns are about common solutions to common problems.
… they are concepts, not blueprints; ideas, not finished designs.
… they add clarity to an otherwise difficult situation.
– Brandon Savage, Practical Design Patterns in PHP
Starting out on a lighter, introductory note, Brandon explains the need for frameworks, argues that OOP doesn’t mean just wrapping stuff in classes, and goes into detail on why design patterns appear to be difficult to learn. He then continues with a mild introduction into SOLID principles, and lays the groundwork for more advanced concepts. He explains why each SOLID rule is important and what it means. Given that SOLID is a well established software design principle, it’s only natural to compare it against every pattern that’s about to be explained in the book. Or, to be more precise, to assess how well each pattern respects the SOLID principles, while providing the developer with its intended functionality.
If I express matters in Dreyfus model terminology, he claims the book is there to turn a novice into a competent level developer without subjecting them to advanced beginner mistakes when, in fact, such an approach to learning is not entirely possible – that’s just not how the human knowledge acquisition process works.
As it might not be overly evident from the ToC, the patterns explained in this book are, in order:
- The (Abstract) Factory Pattern
- The Singleton Pattern
- The Builder Pattern
- The Decorator Pattern
- The Adapter Pattern
- The Bridge Pattern
- The Facade Pattern
- The Strategy Pattern
- The Mediator Pattern
- The Observer Pattern
- The Chain of Responsibility Pattern
- The Iterator Pattern
- The Composite Pattern
- The MVC Pattern
- The Domain Model Pattern
- The Active Record Pattern
- The Front Controller Pattern
With so many patterns covered (and most covered well), I was surprised to see a sentence such as “[…] For example, the Registry Pattern (not covered in this book)…“. Why not? The Registry Pattern is a popular pattern, and very simple to explain even if it isn’t exactly recommended nowadays.
Pattern by pattern, each is explained well and most are followed by code examples demonstrating their potential implementation, though I do have a gripe with the factory pattern example with the cache.
The pattern is realized on an example of different caches – APC and Memcache – and both are spawned through a factory, which is injected into whichever service needs a cache component.
It makes sense to me, but I can see less experienced people wondering why one might actually need the Factory step at all, and not simply type hint the cache interface itself in the constructor, requiring the injection of the cache object itself, and not its factory. The current example features both a Factory interface and a Cache interface, and at the very least, one seems like a surplus. This was never explained in a mid-level developer approachable way, and I fear it may be confusing to some. I’m also less than happy with the Bridge pattern’s explanation – it seemed lacking, like it was only scratched at the surface, never to properly return.
On the other hand, I absolutely loved the Composite pattern explanation and its demonstration on very interesting Tree examples – the author builds a composite tree with an arbitrary number of nested node levels which applies fantastically to menu construction, hierarchy representation, and more – and I was particularly thrilled with the Decorator pattern explanation. It was done in a very approachable way and on good, usable examples. This pattern in particular was one I’ve always had difficulty explaining to people out of the blue when asked, and I’ve yet to find a better breakdown than in this book.
Neglect of Models
In one instance of the book, Brandon says that models are the heaviest lifters of an MVC application, containing all the business logic and validation code. This is a statement that’s far too absolute for me to accept – off the top of my head I can think of an example where this is not true: Laravel. With Laravel 5 coming out and adding Form Requests, the models will be growing even lighter.
Granted, some people tend to put everything and the kitchen sink into the models, but there are people who put the same amount of god-code into controllers, too. My experience and preference say that everything framework-related should be very light (small controllers, small models, small or no views), and everything service-related (services, plugins, libraries, helpers) can be as fat as they need to be, as long as they’re inter-operable between frameworks. That’s personal preference though, I suppose. One other thing struck me as odd, though:
“Creating good models is one of the most complicated tasks any developer tackles. For a long time, the Zend Framework documentation held that there was no Zend_Model class because creating a model is the bulk of an application development process. To create a Zend_Model would be to assume that everyone could or would want to use the same model structure, which would be impossible For the same reason I haven’t included any code in this chapter.”
While this does make sense, exemplifying the value, gateway and storage object in the simplest of manners would have been incredibly beneficial to people being introduced to the domain model pattern for the first time. The Domain Model Pattern was, in my opinion, too neglected and far too theoretical in this book.
The Curse of Knowledge
Throughout the book, Brandon makes references to advanced concepts (ORM, inheritance, dependency injection) and third party content without linking to it (Gang of Four), assuming the reader is familiar with it all. The Gang of Four in particular is mentioned on several occasions, and could use at the very least a link to Design Patterns – else the “novice” and “advanced beginner” reader will just glance over the sentence in confusion.
In other cases, the paragraph structure is written in a way that’s far beyond the level of understanding for a novice to intermediate user:
It’s an age old question many developers struggle with all the time: if I am working to invert my dependencies and not create objects inside my classes, how do I go about creating the dependencies that I need during runtime that can’t necessarily be injected?
This is not at a level that’s consumable by the reader who would need this book to become familiar with the patterns. The reader who understands this sentence in full is likely already fully familiar with all the patterns in the book, thus bringing into question the real target audience. I believe this is due to Mr. Savage suffering from what is known as “the curse of knowledge“.
Wikipedia defines it as such:
The curse of knowledge is a cognitive bias that leads better-informed parties to find it extremely difficult to think about problems from the perspective of lesser-informed parties.
The curse of knowledge is a very common occurrence in professionals who aren’t formally trained to pass on what they know, but is also something that does lose effect with time, experience and feedback. This is also why we at SitePoint encourage people to give us honest feedback about our posts, and is why we try to make things simpler and more streamlined with every new publication. No one is immune to the Curse – some are just more affected by it.
The Plague of Self-Publishing
In recent years, self-publishing seems to have really taken off. Those that don’t resort to Leanpub go fully solo, like Brandon did with this book. While this approach does indeed speed the process up and allows experts to put quality content into the hands of interested parties at an alarmingly rapid pace, it also allows for more mistakes, bad content, and typos to slip through.
Most of the problems that plague other self-publishing writers also, unfortunately, plague this book. Lacking an experienced editor, there seems to have been no guidance on content, form or even grammatical and syntactical accuracy – something people who are native to a language often mess up.
Thinking that native speakers don’t make mistakes and thus don’t need formal editing is akin to, for example, a Y-based company hiring someone from country X to proof-read their X-language version of the site on the sole grounds of the proofreader being a native speaker of language X. You really wouldn’t want to hire me to proofread your Croatian version of a website even though it’s my native language, but you’d be hard pressed to find a better English language editor.
As an advanced user, I had previous knowledge of most if not all the patterns explained in the book. However, the explanations I went through were well formed and approachable to an intermediate user – though in my opinion, not to one of lower skill. While the content of the book is very good and Brandon is excellent at demonstrating in code what the theory describes, I feel like the book as a whole is far too complex for the newbie developer to get anything tangible out of.
The PHP community in general, it seems to me, is suffering from a sort of “missing link” syndrome where we have the absolute beginner books (“this is echo, this is a function, this is a php tag”) and the intermediate++ books like this one, or anything Sturgeon, Jones, Hartjes and others have put out, but there’s a middle ground that remains void of quality content and can only be conquered via the good old “throw me into the fire” approach.
That said, if you’re an intermediate developer looking to get into patterns and out of those awkward nods at conferences where people standing around you talk about them but you don’t understand a thing – definitely get this book. If you’re a newbie, I can’t recommend you buy this – not just yet. Master your “echos” first, learn what Composer is, then sink your teeth into this one.
In fact, if you ARE an advanced beginner (beginners should start at the very basics) who’s interested in patterns nonetheless, I applaud you and offer the following resources to look at before you dive into this book:
Content-wise, I’d give the book a 4/5, but taking into consideration the rush job it appears to have been near the end, the typos and language errors (though to be fair, there is a typo submission Github repo which I’ve already polluted with fixes) and the evident lack of professional guidance along with some oddities that I personally believe will embed wrong values into newbies stumbling onto this book (starting class names with numbers in various code samples), I’m ending the final score at 3/5.