Slashdot Mirror


Holub on Patterns

James Edward Gray II writes "Apress sent me a copy of Holub on Patterns for review, and for that I'm extremely grateful, because this is a gem of a book I would not have liked to miss. Odds are, most object-oriented programmers will feel the same, so allow me to share the highlights." Read on for the rest of Gray's review. Holub on Patterns: Learning Design Patterns by Looking at Code author Allen Holub pages 414 publisher Apress rating 9 reviewer James Edward Gray II ISBN 159059388X summary Design Patterns taught through Real World Programs.

If I can level any complaint against this book, it's probably that the title doesn't properly convey the goodness locked within. Holub on Patterns is short for Allen Holub on Design Patterns. Allen Holub is a long time expert on Design and Design Patterns, so he's the man you want to learn it from. Still, if I could name this book, it would be Object Oriented Design Voodoo. (Note: This is probably why I don't work for Apress or any other publisher.)

The book's subtitle is "Learning Design Patterns by Looking at Code." That probably conveys the work's focus a little better and it also gives away one of the book's best features: sensational examples. (These examples are in Java, another area where Holub is a well-known authority, but the concepts taught apply to Object Oriented Programming in any language.)

Titles aside, this book really is the best work I've read on design patterns. If you don't already know, design patterns are the recurring patterns of object-oriented software implementations. Luckily, you don't have to know anything about them to read this book. The author covers many patterns in rich detail from the beginning. Even if you do know your design patterns well, I'll wager Holub still has a trick or two to impress you with.

Holub discusses patterns in their ideal pure form, but much more importantly he shows them as they occur "in the wild," with multiple variations. He covers the downside of each pattern, weights the trade-offs of using them, and even gives a handful of cases where he felt they were impractical. He does all this right in the middle of complex real-world examples so you can see each point he's making. That's actual programming, folks. The good, the bad and the choices we programmers make are well presented, and that's rare in a programming text.

The book opens with two chapters that more or less cover why we need design patterns at all. Did you know getters/setters are bad? Did you know that subclassing is dangerous? If you said No to either question, you need this book and these two chapters in particular will get you up to speed on good OO practices. This section of the book is mostly theory, light on examples.

The next two chapters (covering over 250 pages) make up the heart of the book. Holub examines two examples in exhaustive detail. The first is his implementation of The Game of Life. You've probably implemented that on your TI calculator, but Holub sure didn't. He admits that his implementation is "Toy Code," but it's a robust example that involves eleven design patterns. The second example is production code, a mini database complete with SQL interpreter. This code is also swimming in pattern usage, and Holub gives you the guided tour.

I've already said these examples are great, but that claim begs some elaboration. First, we're talking about hundreds of lines of code in many of these listings. These aren't the usual contrived junk. What's more, one class may be participating in multiple patterns. Making any sense of these examples would be almost impossible if the author wasn't flawless in explaining the key points and always dropping hints about what you need to notice. This isn't light reading. It's work, but the rewards are there and it'll pay off if you really spend the effort to understand how the code works.

Finally, the book closes with an appendix that gives more typical recipe-card style listings of all the design patterns discussed throughout the text. This is a nice reference after you've finished the tricky stuff. If you're new to design patterns, you might start here, before the book throws you into the lion's den with its massive examples.

Just in case I haven't sold you on this title yet, I better mention the gorgeous hard back binding. Brilliant and sexy. How can you beat that?

Holub on Patterns is a very approachable way to learn a lot about design patterns. If you already know how much patterns can improve your object-oriented programming, you'll really enjoy Holub's presentation of the topic. If you don't yet grasp Design Patterns or haven't enjoyed other works on the subject, you'll just have to trust me: You want this book.

You can purchase Holub on Patterns: Learning Design Patterns by Looking at Code from bn.com. Slashdot welcomes readers' book reviews -- to see your own review here, read the book review guidelines, then visit the submission page.

16 of 211 comments (clear)

  1. Getters/setters bad? by d_jedi · · Score: 5, Interesting

    The book opens with two chapters that more or less cover why we need design patterns at all. Did you know getters/setters are bad? Did you know that subclassing is dangerous? If you said No to either question, you need this book and these two chapters in particular will get you up to speed on good OO practices.

    Can someone explain why accessor and mutator methods (I assume this is what he means by "getters/setters") are bad?

    --
    I am the maverick of Slashdot
    1. Re:Getters/setters bad? by UWC · · Score: 2, Interesting

      I was recently reading up on .net stuff and came across a description of properties. My previous exposure to design patterns was pretty much exclusively C++ based. I agree that addressing simple actuator and mutator functionality would do well to be treated at a lower level than method calls, but I had never come across the concept of properties like that. The examples in what I was reading used C# but apparently properties are also usable in the other .net languages. Is such an implementation fairly new, or at least not introduced widely to C++ until .net?

    2. Re:Getters/setters bad? by Cyberfox · · Score: 3, Interesting

      Greetings,
      Data objects are just groupings of data. The member variables should be public and accessible to it's users.

      This is the only thing I disagree with in that. I believe that a get/set interface to data objects is in fact the only right place for get/setters.

      Why? Because you might want to abstract that data object into something more intelligent in a later refactoring, and then you have the burden of replacing every variable reference in everything that touches that class. Nasty, nasty stuff, and it's better to design that nastiness out in the first place.

      I believe in no public member variables, as a general rule (breakable, of course, on occasion, but terribly rarely), as it causes too tight a binding between classes and the value objects that are passed around (called 'tying' by some). This may put me at odds with Holub (I haven't read this book yet), but it wouldn't be the first time.

      Holub is an EXCEPTIONALLY good introductory author, very easy to read, and clearly brings you to the point he's trying to make. However, I recall coming back to his C books after many years as a professional developer, re-reading them out of curiousity, and realizing that he was teaching a few principles that were questionable at best, and ignored at-the-time best practices. Now it's very possible that he would also think they are questionable these days, but putting them in a book lends them an air of authority through time.

      I'll probably pick up the book, as more examples of good pattern use are always valuable, but as an engineer who has developed countless classes where 'value objects' become more intelligent, I strongly recommend against direct member variable access.

      -- Morgan Schweers, CyberFOX!

  2. Applicability to other forms of development by nanter · · Score: 4, Interesting
    Object oriented patterns are great, and there have been numerous books written that have covered some of the most valuable OO patterns in use. I've recently started work in service oriented architectures, however, and I've noticed that shifting from an OO mindset to an SOA mindset can at times be more challenging than the switch from procedural to OO. Given that the guts of the web service implementations are often in OO, and these patterns can thus be applied there, has anyone seen any good treatises on SOA patterns yet, be it online or in book form? What I've seen has been pretty preliminary and basic. Given the immaturity of SOAs and the thusfar slow adoption of them, it's not surprising, but it would be nice to have some 'pattern gurus' apply their skills to both SOA patterns and the interaction between SOA patterns and the existing OO patterns.

    In the interim before the appearance of such works, I've been trying to keep an informal list of patterns I've unearthed through practice, but my ability to codify patterns cannot match that of someone like Holub. :-)

  3. sounds promising by magicmonster · · Score: 2, Interesting

    This sounds promising. I've been waiting for another book besides design patterns by the gang of four, and specifically looking for one with nice Java examples. The other design patterns books I've found are all geared towards J2EE or the enterprise market. Does anyone have a quick table of contents or a list of patterns he covers?

  4. Re:Bring back procedural languages by Greyfox · · Score: 2, Interesting
    Well the reason the technique was originally invented was that the DOD was spending way too much money on software maintenance. Of course, they were trying to maintain millions and millions of lines of Fortran, COBOL, BASIC and Assembler. Who's to say that improvements in structural techniques over the past decade or so wouldn't also have solved those problems?

    Anyway, what I've noticed is that up until the past couple of years, not many people really had an idea of how to do Object Oriented programming all that well. Most programmers were faking it, mimicing the talk out of the various trade rags without really understanding the reasoning behind what they were doing. And you can make some pretty atrocious object oriented designs if you don't know what you're doing.

    OOP doesn't need to be what you've seen any more than procedural code needs to be twisty mazes of GOTOs and global variables. It all boils down to the abilities of the guy writing the code.

    --

    I'm trying to teach myself to set people on fire with my mind... Is it hot in here?

  5. Because OOP Has No Mathematical or Logical Basis by Anonymous Coward · · Score: 1, Interesting
    OOP is the biggest waste of money ever to visit computer science in history. We spend bazillions of dollars to build these giant hierarchies, and then, have to throw them away periodically because they are too rigid...
    All OOP models are unique and therefore different. It is impossible to find a single basis for all possible OOP models. It is often not possible to change an OOP design without restructuring objects and code heavily. Ergo the brittleness of OOP design. This is a fatal weakness to OOP and indeed will lead eventually to it's abandonment.

    In a similar manner object-oriented databases have no mathematical or logical model (wherein one can model any OO database ) and so the relational database model, which can be universally applied to any database and which has a strong mathematical foundation, dominates.

    Someday OOP proponents will realize the futility of their efforts and move to logic programming systems. But such systems are somewhat difficult to master today (look at Prolog) and will need improvement before adoption becomes widespread. Today's "business rule" systems are a sort of hybrid OO-logical mixture that has significant market share.

  6. What about multi-tier? by Spy+der+Mann · · Score: 1, Interesting

    If it wasn't for OOP, we probably couldn't have reached multi-tier approach to programming. Yes, I know, Java sux. But not OOP in itself.

    I program in PHP, and without OOP, I wouldn't be able to use very nifty template classes which simplify my web job, not minutes or hours, but days.

    The problem with OOP is that if you don't know best-use practices and think before writing (i.e. use UML), you're sure to make a bloody mess.

    Think of OOP as 3D as procedural programming was 2D. A building in 3D is certainly more astounding than a 2D plane. But a maze in 3D is much scarier than a 2D maze.

    It's not that OOP is "worse" than procedural programming. It just allows more powerful designs (either good or bad).

  7. The examples sound great, but... by javaxman · · Score: 4, Interesting
    I'd like to see the details of the first section.

    I mean, yea, "getters/setters are bad", in public APIs. Getters are bad- unless you need to vend an object and can't afford the overhead of creating entirely new instances when you do so. Setters are _definitely_ bad- unless they're private or are data that act as input for your object, which it recieves from controller-layer objects.

    Sure, "inheritance is dangerous" as anyone who has ever written an object-oriented program from scratch and had to modify it can tell you. Inheritance is also the key to code reuse, and can be very powerful when done correctly- do you really want to re-write a section of logic that's shared by 5 other objects ?

    These things have their place. They're good targets for "is evil"-type articles because they're often used when they should not be. But to call them "evil" and "bad" without proper qualification? It smacks of unprofessional behavior, at best.

    I'm a bit puzzled by claims that use of getter/setter methods and, more puzzling, inheritance, are indications that you haven't solved your problem in an object-oriented manner, or that your problem isn't object-oriented... because, well... not all problems are best solved by object-oriented methods, even if you're using an object-oriented language to do so. Sometimes, you need a variable and a loop... what's wrong with that?

    At some point, my model code is going to have to give my view code some objects to display... what, I'm not supposed to use getters there? At some point my view code is going to want to tell my model code about an object the user modified... I'm not supposed to use a setter there? I often think folks who write such blanket statements as "accessors are bad" are just trying to spark some flames.

  8. Intuitive by roman_mir · · Score: 5, Interesting

    I didn't find it in many programmers I worked with, but personally I find all of the advices in this book intuitive. What I did find in many programmers is the rigidness they assume when someone questions their position on some specifics. I remember a few conversations I had where I questioned the entire OO paradigm, the people look at you as if you are mad.

    But the reason why I questioned the OO paradigm was not the paradigm in its purity, but the implementations that I so often saw in real life. Some of the architectural designs that I witnessed did not make any sense and were artificially created to be more complex than the problem at hand required. What is worse, I have seen 'architects' who got into those positions without any merit. I have witnessed architects who think their position is justified because they spend another 4 weeks in the beginning of every project 'rethinking' the ACLs. I have witnessed an 'architect' that was supposed to design a system, but who instead sat down with a programmer, did a bunch of handwaving, and left the programmer without any idea and without documentation on how things are supposed to be done, and it was not a simple thing for that guy who was still a beginner. I cannot count the number of times where I (as a contractor) in different companies was put into a position where I had to solve the problems created by these 'architects' as well as by 'managers' and the marketting people.

    Yes, I remember having a conversation about getters, setters about 4 years ago, I was convinced that those things are a horrid idea as well as extends (for almost the same reasons given in the article). I was attacked on more than just the techno-level. It is hard, it is not easy at all to work around bad design decisions, where someone just does something because it is either a pattern they read, or the marketting says it has to be done that way because there was this meeting with an IBM guy, who bought all the managers year-long golf memberships.

    What I appreciate in people is the ability to think for themselves and to make decisions on when something is appropriate. I am also a realist, I know that noone on this planet can be perfect 100% of the time. We get tired, we have schedules, we just want to do things fast and dirty, we resist structure because it is easier that way. But those of us who are good enjoy going through all of this nonsense and figuring out sensible ways to still deliver a good system.

  9. (not) Short Plain-English Version Answer by IBitOBear · · Score: 2, Interesting

    Ok, to summarize his point. If you are making a "thing" then the operations on that thing should be contained inside that thing. So if you make these little routines that do nothing more than let you peek into "thing" to see "the real thing" inside, your "thing" isn't your friend.

    As a peice of mental oragmi (and to fold my own self in here, instead of _just_ trying to paraphrase this guy).

    There is nothing wrong (IMHO) to exposing parts of your thing via accessors and setters AS LONG AS you think of these methods as "translation to the outside world".

    That is, if you find yourself writing NewThing.setValue(OldThing.getValue() * 5) then you are no longer getting any useful work out of having "thing" in the first place, and this is bad. It's bad because you are requiring yourself/the world to reach behind a blined and operate on something that you hope will remain stable.

    Accessors and Setters are "good", however, (my view, not his) when you lear to see them as moments-of-control that you wrap around the need to communicate "parts of thing" with the outside world. These moments of control may involve locking or provide you the opportunity for "lazy evalutation" of a "thingness" that might exist in any of several forms. For instance, in TCL all of the values exist as this mutable state of "string or whatever". If you are working with the value as a string then it is best represented internally as a string; if as an integer then as an integer; etc. So having a getValueAsString() and getValueAsInteger() accessors make sense as they have that opportunity to do things while communicating with the outside world.

    Such an enlightened thing should, however, have a [+= int] operator, and that operator should be used in global preference to dong set(get()+X).

    So it isnt "really bad" to offer the user the opportunity to communicate with your object, but if you find that the objects *prefer* to be tweaked via this communication, then you have made a mistake that will cost you a lot _eventually_.

    In practice, you can avoid this trap by being liberal with the getters but stingy as heck with the setters.

    For instance a network socket object should have a lot of getters for things like "local address" and "peer address" and "lcoal port" and "general health"; but you don't want to "set peer address then connect" you want to socket.connectTo(PeerAddress).

    Anoter example is "const string & someImportnatValue()" where your object maintians some important string and you might want to let the world examine that important value. But you don't ever let the world "replace" that value whole-scale. You allow the world to opperate uppon the thing, which *may* change the string too.

    So expose spesific items of interest through accessors, but only provide "operators" as a means of changing what must change.

    After all, if someone can just set a value, then how do you maintian your invariants (requirements of state)?

    If you have written a true operator that you have chosen to call "set", then your name is probably wrong at least.

    It's a distinction between grays in many cases.

    Rule of thumb: the code that changes a thing should be owned by the thing. If you are "borrowing out" some key value, operating on it in the wild, and then "putting it back in" you are probably making code that will cause you harm, because now everybody is "diddling" your state in their alien and undefined-to-you code.

    It's bad to be everybody else's (deleted).

    --
    Innocent people shouldn't be forced to pay for inferior software development.
    --"Code Complete" Microsoft Press
  10. Re:Another pompous "expert"? by MarkusQ · · Score: 2, Interesting

    Strongly typed != Statically typed

    You are confusing two concepts here. Smalltalk, for example, is dynamically typed yet it doesn't have all the casting about that C does; the typing is strong and dynamic while C's is static and weak/leaky. What gets you into trouble is the weak/leaky typing, not the dynamic typing.

    -- MarkusQ

  11. Ruby Needs Data Encapsulation Too by Bbazzarrakk · · Score: 2, Interesting

    Poor guy is stuck in a statically typed Java hell, with distinctions between primitive types and objects, of course he's gonna think getters/setters are evil and he's gonna become obsessed with keeping his data hidden in a box or behind opaque methods! I can just imagine his code filled with thousands of builder objects with 2-3 levels of abstraction .. and it will just be a grotesque simulation of a true dynamic language in the end, with everything completely decoupled.

    This is totally off base. You're missing the point. This isn't about typing, it's about Data Encapsulation.

    Pop quiz, in Ruby no less. You have a class:

    class BankAccount
    attr_reader :balance
    def transfer_to(other_account)
    ...
    end
    end

    When your balance is off at the end of the day, you know where to look for errors. One of your methods, probably transfer_to(), is causing the problem. Change attr_reader to attr_accessor though, and then where do you check? Answer: The Whole Wide World! Good luck finding it, you'll need it.

  12. Re:Should be titled "Holub on Java Patterns" by rivermaker · · Score: 3, Interesting

    There is a good presentation on how the dynamic languages make the patterns trivial/unnecessary; written by Peter Norvig. Check out http://norvig.com/design-patterns/

  13. real world not by Anonymous Coward · · Score: 1, Interesting

    I studied programming with Allen Holub, and can truly say I became a 'real programmer' under his tutelage. He's a literate and broadly intelligent man, and if I can boil what I got from him down to one sentence it would be: programming is writing. You know, like writing an essay or a novel. It should be clearly structured and readable by human beings.

    Beyond this, though, I think he's taken a bad turn. I haven't read the new book, but familiarity with any real-world programming is not Holub's strong suit. In fact, his dedication to strict OO procedures betray his lack of familiarity with the requirements of real jobs, where you're always forced, by changing requirements and time pressures, to make something of a mess.

    The 'game of life' example sounds typical: take a simple problem, implement a solution in a long-winded language (java), making the whole thing even more long-winded by adherence to preconceived pattern methodology, and you end up with a big enough mess for it to look like a 'real-world' program. But the situation is as artificial as any bubble sort assignment in a beginning programming class.Examples like this have zero relevance for what most programmers face when they are on the job: here, modify this million-line program which no-one really understands to fix this bug or add that feature.

    Let's realize what computer programming usually is: the creation, under great time pressure, of temporary solutions to problems which will go away or change soon. Worrying too much about purity of structure and reusability is not only unnecessary, it often paradoxically has the effect of creating programs too rigid to be modified over time as requirements change.

  14. Re:Another pompous "expert"? by elbobo · · Score: 2, Interesting

    Indeed. The irony is the comment opened with a negative reference to a paper on how people with substandard knowledge often presume themselves to be more capable than they are. Looks like he walked right into that one.