Wednesday, March 26, 2008

Comments on Head First OOAD -or- The Fanboy Speaketh

A while back, I read Head First Design Patterns almost solely because the sample chapter I downloaded was so effective at making the Decorator pattern seem obvious, to the immediate benefit of understanding how Java I/O streams wrap around one another. I became a fan of the "Head First" approach, although I stopped short of buying the design patterns poster. My second "Head First" book, Head First Object-Oriented Analysis and Design, hasn't dampened my enthusiasm. As you would probably guess, this book is about the up-front tasks of software development: gathering feature lists and requirements and use cases, decomposing larger tasks into smaller, focusing on eliminating overall risk, determining how to divide a process among objects, writing tests, and ensuring the code is written with reuse and extension in mind.

The style of these books is so jarring that it needs a rationale. Hence the books use the intro partly for that very explanation and partly to advise the reader on how to respond. My opinion on the Head First formula is mixed. For dull nonfiction, expressing information visually is more memorable and expressive than words; developers who've never read a "Head First" book still make diagrams at work. Exercises and thoughtful questions are good for keeping the reader engaged. Have other books ever asked so many questions all the time? (Such a strategy is reminiscent of the well-known study technique of raising and answering mental questions of the text while reading it.) I also appreciate that the text describing images/code is in nearby snippets with clearly-pointing arrows, like the "word balloons" of a comic strip or an application tooltip. Each snippet is thereby closely associated with its object, trimmed down to an inviting size, and yet stimulates sustained, active attention because the eye must rove to keep up.

Nevertheless, the layout has its downsides. Sometimes, conversational writing is too conversational. I prefer terser, denser language. On the other hand, the readability and redundancy ensure that the intended point is unambiguously communicated, and the "there are no Dumb Questions" Q&A sections are excellent--from time to time the questions matched my own misgivings perfectly. The humor flops more often than not, but I realize a failed joke is still more interesting than no joke. Packing fewer of the repetitive images into each page, or shrinking the images, would leave more room to introduce ideas. Smaller font sizes in some cases would also conserve space, averting the occasional sensation that the reader disproportionately paid for a lot of blankness. Widespread images, varying fonts, and free-form positioning enhance both enjoyment and impact; however, here and there these books sprint into flying leaps off the deep end. I imagine OOP books are especially suitable for illustrations.

Regardless of style, the content is superb, as the quoted reviews mention. It's not advanced or has a grab-bag appendix that swiftly summarizes extra subjects like the design patterns book's appendix of extra patterns. Its explicit purpose is to show and tell how to use a collection of procedures and guidelines to make great software. Some might argue that all professional developers should already know (have been taught?) this material. While that's true, that also presumes too much about the "education" of a "professional" "developer". Taking some Java classes doesn't imply that someone also has good grounding in OOAD, nor that someone groks the goal of and reasons behind object orientation. At the same time, OO development in languages besides Java can benefit from this knowledge.

Like the title indicates, this isn't a "Java book" just because it contains Java-only code. As with Head First Design Patterns, the topics are in context because vital underlying principles persist throughout. Chapter 8's sole focus is design principles. I wasn't expecting a mention of the Liskov Substitution Principle, but there it was. (What I expected even less was the clue in the end-of-chapter crossword to call Liskov "he"!) Other fundamentals included encapsulation, inheritance, polymorphism, delegation, composition, aggregation, DRY, cohesion, single-responsibility principle, interfaces, coupling, design patterns.

Again, some might argue that those concepts should be common knowledge (or, worse, some might argue the concepts are common sense). While that's true, the genius of "Head First" is intermixing principles and prolonged scenarios. Instead of generally introducing delegation and then proceeding to walk through a piece of code specifically contrived for that purpose, "Head First" is more likely to start with a simple yet sufficient situation. After organically producing working but naively-designed code, the situation changes, and as a result the code must be reconsidered. At this point, the problems in the original code become apparent, maybe with some references to previously-covered principles. Then delegation as both a general concept and specific solution comes into the picture and improves the code. This method works best when the first-time reader isn't skipping around the book. It also means that the summaries and bullet points at the end of each chapter are better for reference than the chapter itself. The fully-descriptive table of contents aids in reference, too.

Thus, this book has a strong practical bent along with its OOAD generalities. Its stated, oft-repeated emphasis is to make great software. And great software does more than function. It meets the customer's needs and supports change and reuse. To the degree that a technical book has a major theme, its theme is change. Requirements change. Designs change. Objects change, though each one should change for only one reason. Another book might have code that's perfect when it appears, or portrayed as perfect. The truth is that OOAD doesn't lead to one right solution for all time. In fact, a frequent side comment in the exercise answers, perhaps inserted to reassure perfectionists, is "don't worry if you may not have come up with this exact solution, but yours should have contained _____ ". Readers who become frustrated with the multiple revisions of the designs and code are missing the point. They may also simply be doing what I did with the inventory search example: anticipating the eventual shape of the code in later chapters. (My thinking at the time was "What?! I would have used an interface to achieve looser coupling, because there's no need to assume anything more about the shape of the object(s). I guess I'll just smugly keep my superior design in mind, and continue reading." I was gratified when mine showed up many pages afterward. The fictional customer forced a design shift.)

The two "Head First" books I have contain sizable amounts of real, minimal code despite being about rather high-level, abstract parts of software development. Since unapplied principles don't matter, connecting principles and code and "real" pictured entities is a reasonable way to teach them. Look past the goofy pictures and one-liners. A relative lack of information density is offset by a dogged determination to engage and inform, to spread practical and usable knowledge. If the table of contents has items someone would like to know better, I'd recommend learning those items via this book. Chances are, by the end he or she will have absorbed unexpected tips that will prevent future development pain...

No comments:

Post a Comment