1. 26

  2. 10

    This is a really nice post. (It’s a reflection on the book “Design Patterns”, by the “Gang of Four”.)

    The complaints that the book is “outdated” (it was published in 1994) strike me as similar to complaints that “The Pragmatic Programmer” is outdated (hardly discusses F/OSS, predates the ubiquitous web) or that “The Mythical Man-Month” is outdated (uses examples from mainframe era, has some gauche language choices).

    Pretty much any book about “modern” software programming “techniques” is “outdated” within 10 years of publication, and especially so if it was published in the 70s, 80s, 90s, or early 00s. I believe you have to read these books in their time and place, and draw out the timeless lessons while recognizing and chucking the junk that doesn’t hold up to the passage of time, and to the new industry state-of-the-art.

    “The Pragmatic Programmer” recently got a 20th anniversary 2nd edition update/revision, a rarity in the world of classic texts in programming. Here was a quote from the preface, which can also be found freely online:

    Back in the 1990s, we worked with companies whose projects were having problems. We found ourselves saying the same things to each: maybe you should test that before you ship it; why does the code only build on Mary’s machine? Why didn’t anyone ask the users?

    To save time with new clients, we started jotting down notes. And those notes became The Pragmatic Programmer. To our surprise the book seemed to strike a chord, and it has continued to be popular these last 20 years.

    But 20 years is many lifetimes in terms of software. Take a developer from 1999 and drop them into a team today, and they’d struggle in this strange new world. But the world of the 1990s is equally foreign to today’s developer.

    The book’s references to things such as CORBA, CASE tools, and indexed loops were at best quaint and more likely confusing. At the same time, 20 years has had no impact whatsoever on common sense. Technology may have changed, but people haven’t. Practices and approaches that were a good idea then remain a good idea now. Those aspects of the book aged well.

    So when it came time to create this 20th Anniversary Edition, we had to make a decision. We could go through and update the technologies we reference and call it a day. Or we could reexamine the assumptions behind the practices we recommended in the light of an additional two decades worth of experience.

    In the end, we did both.

    As for “Design Patterns”, I always read this book as an exploration of object oriented programming design, at a time when there was, for better or worse, only a single mainstream “truly OO” language, namely, C++. (Yes, there was also Smalltalk and CLOS, and perhaps others, but hardly mainstream.)

    The book then had a huge influence on Java programmers, and Java was the first time you saw dynamism (e.g. classloaders, reflection, garbage collection) and OOP mixed into the mainstream of programming, as well. It’s true that as time went on, certain languages incorporated “design patterns” right into the language. For example, Python has Iterator, Interpreter, Facade, Visitor, and Decorator built-in, and probably a few others.

    The book had a big influence on me in the 00s, because it just got me thinking about programming abstractions independent of data structures. What you might call “the ergonomics of code”. So I am still thankful to the book and vocabulary it introduced.

    I think it’s far too easy to take programming books of a prior era and discount their value altogether just because the tech fashions have changed. It’s a pity – there is a lot of wisdom that knows no age, even in our field of neophiliacs.

    1. 2

      I think it’s far too easy to take programming books of a prior era and discount their value altogether just because the tech fashions have changed. It’s a pity – there is a lot of wisdom that knows no age, even in our field of neophiliacs.

      I am, to this day, grateful to a professor in the mid 90s who handed me a copy of Brooks (Mythical Man Month) and encouraged me to read it one day when I visited his office hours. Our conversations after I read it and asked (in puzzlement, not as a challenge) how it could still be relevant inspired me to reserve judgement. Observations during my first big project at my first big corporate job convinced me firmly that what you say is correct.

      1. 3

        Brooks is “special” because the stuff he writes about are basically how to organize a business - but with software! In his time, the art of planning how to make widgets was well known - so and so many man-hours per part, so-and-so much material, so-and-so many factory square feet. Software was different - or is different. Brooks was a corrective to the idea that if software was late - just add more programmers, like you’d do with a factory line.

        The fact that Brooks still teaches us these lessons is an indictment of the education of those that plan and lead software developments - or it’s because developers aren’t as easy to push around as factory workers.

        1. 1

          Brooks also advocated for a team structure where 80% of people are doing what amount to clerical work, while only one or two are allowed to contribute code to the product.

          It seems quaintly archaic in a time where modern tooling like Git and CI/CD eliminate so much of that support burden. Hell even the C linter (1978) didn’t exist when Brooks wrote his Imaginary Individual-Increment (1975).

    2. 7

      Design Patterns is better understood if you understand that in the 80s and 90s (which I didn’t experience as the metaphorical dark ages the author invokes), people expected and hoped that the software industry would become dominated by OEMs making components in object oriented languages; pretty much what the automotive and electronics industry are like now.

      In a world like that, it pays to have a very versatile and popular component. So before you ship yours, you have to think long and hard about the ways people may want to use and extend it. That’s what makes Design Patterns worth reading, the way the authors think extensively about design decisions, and how they may hinder or facilitate further use.

      They used the metaphor of Christopher Alexander’s Pattern Language; programmers building a nice neighborhood for each other, employing patterns to consider each others’ wishes and needs. It’s a very social and romantic view of software development.

      The actual way the Computer industry solved the problem of duplication of effort was with open source. Not only is there an infinite variety of ‘components’ to choose from, the components themselves can be modified at will. Writers of a component don’t have to anticipate every possible use case, as the users will write a patch if necessary.

      1. 2

        Very well said. The design principles discussed in the book are probably better applied to designing public and hard-to-change APIs (like HTTP/REST APIs), rather than “all modular code”. Modularity is usually better achieved with simple functions, rather than classes and type hierarchies – that’s a lesson that would become strikingly clear in the era of open source Python. I discuss this in my Python style guide here.

        To illustrate: the requests module is a great example of modular re-use because it hides most of the gnarly details of making HTTP requests behind a simple function: requests.get(...). Rather than exposing a deep class hierarchy modeling HTTP (as is common in Java HTTP libraries), and a wide set of methods or interfaces that you need to couple your code to. You just call the function, get a simple return value, and you’re done. Low coupling, low mental overhead, high re-use.

        The book “The Philosophy of Software Design” comes up with a great name for this distinction: “deep vs shallow classes/modules”. You can see the reference visually in this tweet.

        1. 1

          Yes, and the stereotypical discussion about Design Patterns was one between Java engineers designing an internal API that could be changed on a whim. YAGNI

          A Philosophy of Software Design sounds interesting. I’ll check it out.

      2. 6

        The trick to these kinds of books is to understand if you have a problem of any technical significance and you can code well, you’re going to end up here anyway. No point reinventing the wheel.

        The two mistakes are 1) not reading the book, and 2) reading the book and blindly applying patterns everywhere. God, I’ve seen some ugly code where both of these happened.

        The more and more layers we add on the stack, the more creating technology is like ice skating across a very deep pond. You don’t want to dive down deep at every little weak area. Instead, you want to consciously pick the areas where depth is needed and then use only as much as you need.

        1. 2

          So much this. Many years ago we kinda agreed that you could sum up the book as “codified names for common sense”. Often overengineered, sometimes just what 3 out of 5 normal programmers would do (in some form) anyway.

        2. 4

          I’m not sure the article makes a good point – sure bits and pieces are used, but often in a substantially different context.

          Cherry-picking the few things that survived to construct an argument about the relevance of the book as a whole is rather unconvincing.

          1. 4

            Design Patterns is an interesting read but it is also heavily grounded in vulgar OOP.

            What is a good collection of design patterns for functional languages? Types? Declarative languages?

            1. 2

              I’ve gotten some value from Enterprise Integration Patterns because it describes patterns that arise among programs rather than within them.

              In practice, we often need to exchange data with a system owned by another team. We don’t have control over the technology they’ve chosen, but patterns like “content-based routing,” “request reply,” and “envelope wrapper” are still pervasive in distributed systems, no matter the programming language.

              1. 1

                Peter Norvig’s Design Patterns in Dynamic Programming is a great antidote to the GoF book.

                1. 1

                  It’s very Python-specific, but “Fluent Python” does a nice job mixing a discussion of language features, style, idioms, and patterns in a unified way.

                  For functional languages, the closest I’ve come across is probably “Elements of Clojure”. But I think it’s a little more abstract than you’re suggesting, focused more on abstract design areas rather than concrete patterns.

                  For Java and more traditional OOP/imperative languages, “A Philosophy of Software Design” is a nice read in this category. It’s also a bit more abstract than “Design Patterns”, but I think also has a better shot at a density of timeless insights as a result.