Episode 64: Using Pattern Languages for Object-Oriented Programs

This episode looks at the origin of design patterns in software, their development, and the limited exposure many software engineers have to the idea. The episode is supported by members of the Chiron Codex Patreon (use this gift link for your first month free), so please do join the community or hit the Ko-Fi button to make a one-off donation. If you enjoy the episode, share it with at least one friend, colleague, or stranger.

Links

Transcript

Hello, and welcome to episode 64 of the Structure and Interpretation of Computer Programmers podcast. I’m Graham Lee. This episode is sponsored by you, the software engineering community. If you enjoy this podcast, please share the link with your friends and colleagues. You can give feedback on this episode by commenting on the post at sicpers.info slash podcast, that’s s-i-c-p-e-r-s dot info slash podcast, or by sending me an email, grahamlee at acm.org.

Most programmers who have encountered pattern languages in software engineering have read one of two books, either Design Patterns by the Gang of Four, that’s Gamma, Helm, Johnson and Vlissides, or Head First Design Patterns by a gang of four authors, Freeman, Robson, Bates and Sierra. Both books probably sold in about equal quantities, and both represent a tiny window into the world of pattern languages and software.

The Gang of Four book propelled the idea of a pattern language of software design into the mainstream. It was instantly popular when introduced at eCOOP 1993, that’s the European Conference on Object-Oriented Programming, and it remains in print to this day. I have the 32nd printing from 2005, and a book still available in hardcover 21 years later. Martin Fowler called it “the best book ever written on object-oriented design, possibly of any style of design”.

If the Gang of Four book brought design patterns to the mainstream, Head First Design Patterns explained the idea to a mainstream that struggled with the dense style of the first book. However, people came away, whether they had read both, one or neither of those books, with the idea that the catalogue of patterns in the books is all there is to learn, that if you identify state machines in your system and implement them using the state pattern, identify component interfaces in your system and implement them using the mediator or facade patterns, and identify one-off objects in your system and write a blog post decrying the singleton pattern, you’re doing design patterns.

Worst of all, they learned that design patterns are about system implementation, that they tell you something about how to design classes and interfaces in your code, that the appropriate person to apply design patterns is a programmer. In fact, this distortion of the value of pattern languages is so egregious, and yet so successful, that in 1999, the Gang of Four were subjected to a tongue-in-cheek show trial at the OOPSLA, that’s Object-Oriented Programming Systems Languages and Applications Conference. Their charges include having promoted a cult of personality and brought about the establishment of a cottage industry of consultants, trainers and sundry acolytes to interpret their abstruse musings. They are said to have, by making it possible to design object-oriented programs in C++, have inhibited the rightful growth of competing object-oriented languages such as Smalltalk, CLOS, that’s the common Lisp object system, and Java, and by distilling hard-won design expertise into patterns, have encouraged novices to act like experts.

We need to burn everything down and start again. I’ll start with computers, though, and specifically go back to the beginning of applying pattern languages to object-oriented software systems. I already wrote a whole series of posts over on my blog about the genesis and evolution of the model-view controller pattern. Links in show notes. And MVC is almost certainly the first pattern explicitly shared for the purpose of guiding software design.

But the place where people realised this approach to software design, describing a common problem and its solution, packaged in such a way that someone else who has the problem can learn how to apply the solution alongside the problems that they just invented for themselves by doing so, could be a general approach to software design. And one that works well in the object-oriented paradigm was OOPSLA87, and specifically a technical report by Kent Beck of Apple Computer and Ward Cunningham of Tektronix called Using Pattern Languages for Object-Oriented Programs.

Pattern languages weren’t invented by Beck or Cunningham, or even by any of the MVC people, Adele Goldberg, Trygve Reenskaug, and the other Smalltalkers. The idea comes from the world of built architecture, most influentially from Christopher Alexander. He says, despite being a professional architect, that we, humanity, don’t really know how to design buildings, spaces, and structures. He proposes that the best people to design and build a structure, like a building or a town, are the people who live, work, or play in that structure, because they’re the people who know what they need, and they’re the people who will have to adapt to the realities of the structure, assuming it actually gets built.

A pattern language in construction or architecture is a guided tour of the knowledge of that field, expressed in a form that lays out a problem people have, a solution to that problem, how it compares with alternative solutions, and other problems you might encounter by applying that solution, and hence, other patterns you might want to consider. For example, Small Public Square is a pattern that applies to a town. They give people a place to meet, and if town squares are too big, then they feel empty. The existence of a Small Public Square might generate a Promenade, but then you have to think about Pedestrian Density. Both Promenade and Pedestrian Density are other design patterns. This language then forms a shared vocabulary between lay designers and architects, so that the people who live in a town can say, we want a Beer Hall on our Small Public Square, and the architects know what a Beer Hall is, and can ask follow-on questions, say, the number of Alcoves, and the Ceiling Height Variety. Ideally, the pattern language is acyclic, so that at some point you can actually finish designing and get on with construction.

Inventing our own realistic example, hundreds of years ago, many buildings had roofs that were made of thatched straw or rush, and opened fires in the middle of the floor. This worked okay, because the thatch let the smoke eventually dissipate, and in fact the warm, smoky air kept a lot of vermin out of the thatched roof. Over a long period, from the 12th to the 18th centuries, people started building chimneys instead. These are ventilation shafts incorporated into the building structure, that exhaust the hot, smoky gases from the fire to the outside directly. Chimneys have benefits. The air inside the building is cleaner, for example. And drawbacks. A lot of the heat from a fire escapes through the chimney. They also motivate related concerns. For example, you have to get the shape of the flue correct, to avoid blowing air from the outside down the chimney, and distributing your fire throughout the building. And you have to build the chimney from non-combustible materials, for reasons that seem obvious now, but apparently weren’t in the 15th and 16th centuries. These requirements both weren’t understood by builders who saw other buildings use chimneys and copied them in their own short-lived designs.

So an architect might create a pattern called Chimney that solves the problem of smoky air in a building and relates to other patterns like ventilation and fire safety. Then when someone’s talking about heating their office or house, the architect can propose a Chimney, though these days they might want to suggest Heat Pump or HVAC instead.

A pattern language is an evolving argot because our understanding changes and the things we’re trying to do change. Christopher Alexander’s 1977 work on a pattern language for built architecture doesn’t include anything about cell towers, working in coffee shops, or the effects of influencers making TikToks on pedestrian density, to cite a few examples.

This is the advert break.
It starts now.

Your development team is slowed down, your customers are frustrated, and your support team is constantly banging down the door. Nobody can find the information they need, and they struggle to talk to each other to work it out. Relationships on the team have soured, with developers, QA and ops all taking an us-versus-them position. Your backlog grows faster than the team delivers features. Retrospectives involve more finger-pointing than decision-making. This sounds like a case for Software Craftsmanship’s consulting detective. That’s me. Discover your team’s friction points and create realistic action plans for improvement. Restructure your delivery pipeline to bridge the quality gap, automate improvements, and reduce rework. Then, take ownership of the documentation, and curate a knowledge hub that keeps information flowing throughout your organization, empowering engineers, executives, partners, and customers alike. Find out more, and book a free initial assessment at sicpers.info/agency. That’s S-I-C-P-E-R-S dot I-N-F-O slash agency. Together with me, Software Craftsmanship’s consulting detective, we’ll crack the case.

That was the advert break.
It’s over now.

Beck and Cunningham propose applying this idea to software. People who will use the software are the best people to design the software because they know what they need and will have to adapt to the realities of the software, assuming it gets built. So a pattern language of software provides a catalogue of known problems, their solutions, and links with related patterns that a software user and software builder can use to understand the design together.

The new hotness in the 1980s was graphical user interfaces, with Smalltalk being the first environment to both make GUIs accessible and adopts the principle that software is designed and made by people who use it. So the patterns that Beck and Cunningham propose start with interaction patterns for designing software’s user interface. They list five design patterns for windows in Smalltalk. Window Per Task, Few Panes Per Window, Standard Panes, Short Menus, and Nouns and Verbs. Even without the detailed pattern descriptions, it’s clear what motivates these patterns and how to apply them.

Beck and Cunningham explain how these patterns then lead on to implementation patterns, describing one called Collect Low-Level Protocol. Kent Beck eventually published some of these implementation patterns as the book Smalltalk Best Practice Patterns, which I would argue, while remaining conscious that more people listen to Martin Fowler than to me, is truly one of the greatest books in object-oriented design. Even if you never touch Smalltalk and never have touched Smalltalk, read this book, and you’ll learn something about designing software and refactoring, back from before it had that name, refactoring your software towards a design.

Indeed, it was Smalltalk Best Practice Patterns that served as the inspiration for my upcoming book, Patterns in AI Augmented Software Development. Beck described, writing the patterns on index cards that he riffled through when stuck for ideas on the code he worked on. I found things that I, or my colleagues, did repeatedly when trying to get coding assistants to correctly complete a task, and I wrote those on index cards so I could try them again the next time. Over time, and with more conversations with people who use AI tools, I firmed up my understanding of some of the patterns, decided that others weren’t in as wide use as I would want to see to confirm that they represent reusable patterns, and rejected some, because even though people were doing them often, there was no evidence that they help. For example, the Assign Role pattern, where people start a prompt with “You are a principal JavaScript engineer”, or whatever, generally makes things worse.

Beck and Cunningham predict that their pattern language would eventually contain about 100 to 150 patterns. Had they continued, or at least had they published a complete pattern language in the open, they might have completed their work in private. Then their understanding of designing software and of implementing it in small talk would have moved on. People’s expectations of computers would have moved on. Technology would have moved on. And they would have needed to create new patterns to encapsulate that new knowledge. Part of the problem of the design patterns book, the Gang of Four book, is that it’s a single tome with 23 patterns that was published once and not updated. Contributing to the idea that that’s all you need to know about patterns and pattern languages. In fact, just as built architecture, materials science, and human society moves on, and you need new patterns to encapsulate new problems and solutions in the built environment, the same happens in software, society, and people’s interactions with computers, so we need new design patterns. There are plenty of examples from both commercial software engineering, patterns of enterprise application architecture, security patterns, X-unit test patterns, and more. And academia, the whole plot, that’s Pattern and Language of Programming, series of conferences, of people uncovering and documenting new patterns in software design. They just don’t perhaps get the widespread dissemination and use that they deserve, and that the Gang of Four patterns saw. For those who are interested in finding out about the state of the art in design patterns, check out the Hillside Patterncast, a podcast all about patterns in software.

Beck and Cunningham proposed using the pattern language as the primary design tool for object-oriented software, replacing the, quote, usual rehash of tired old ideas, that is the, quote, force-fit of structured analysis or entity relationship methods. We encountered structured programming a little in the NATO Conference mini-series, particularly in episode 63, but an as-yet-unnumbered future episode on Tom DiMarco’s work will look at the structured analysis and design technique in more detail, which is not really related to structured programming. In both cases, the structured word means structure your approach to, not use a language feature called a structure, a semantic distinction that would have aided adoption of object-oriented techniques, if we’re honest. And here, I’m adding a link to my book, Object-Oriented Programming, the easy way into the show notes purely out of spite.

In structured analysis, at a high level, you think about what you need your software to do in terms of the data it needs to operate on, how those data flow through the system, and decompose the system into modules that operate on the data and pass it to other modules. Yes, you could model those modules as objects, but you haven’t got the full benefit of OOP because you’ve modeled data and behavior separately. In entity relationship modeling, you think about the data schema in terms of the entities reflected in the software design and their attributes and associations. Again, this is a whole system approach and, again, you model the entities as static structures that don’t have the dynamic behavior of objects.

However, we’ve ended up in a world in which many software designers don’t use pattern languages for software design and do favor static software implementations even where they do OOP or post-OOP approaches that are object-oriented in all but name like Swift’s protocol-oriented programming and whatever Rust people call what they do where they make objects that send each other messages.

Where people model their software at all they might use something like UML as in my tool Axminster or the related SysML. Those do include objects and message sending including asynchronous messages so they do model the autonomy of objects but they don’t lend themselves well to modeling introspective object behavior for example where an object receives a selector and decides what method it wants to run and they still end up promoting a whole system approach where you think about what use cases you need to support then invent structure and activity that realizes those use cases. There’s no reason why you couldn’t build up say a sequence diagram by role-playing the objects and deciding how they message each other. It’s just that most people start from the outside and model their whole system then generate code from that model.

So a lot of people who don’t want to use the outside-in approach choose the only known alternative modeling approach that encodes dynamism and learning from experience not modeling at all. Or rather they implicitly model the software in software and then ship the prototype to their customers. That build one to throw away that we talked about in episode 58 becomes build one and sell it and then depend on it forever.

Design patterns ought, as described by Alexander and applied to software by Beck and Cunningham, to fill that space. People do rely on repeatable interaction patterns in software design. Think of the Hashtag, Pull to Refresh, or Hamburger Menu. But they don’t use them in collaboration with the people who use their software except when someone sends a bug report that says I think this list ought to support pull to refresh.

There aren’t that many more opportunities for the people who use software to get involved in designing the software that’s voiced upon them unless they’re lucky enough to work with an XP team. Techniques for getting earlier feedback from customers that many teams use like Lean Startup and the Google Design Sprint still rely on a paternalistic designer-knows-best approach where you build something—even if a lightweight thing like a prototype—and then ask people whether they’d use it. The people who would use it aren’t in charge.

At “scale”, podcaster scare quote fingers deployed, the people who use software are the sources of telemetry data and the subject of experiments that explore those data, not the experiences of the people using the software. So, an A-B test might investigate whether people are more likely to press a particular button, not whether they want to do the thing that that button offers, or whether they’d rather do something else.

I previously gave a talk where I said that one of the reasons people think OOP has failed is that they haven’t tried it. Design patterns is a part of OOP that people went significantly out of their way to miss out on.

About Graham

I make it faster and easier for you to create high-quality code.
Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.