If you can't draw a picture of it, it isn't a pattern. -- [Alexander79], p. 267
In the past 19 articles I've written for The C++ Report, I've talked about software patterns that build on Christopher Alexander's patterns for the architecture of the built world. The Timeless Way of Building [Alexander79] and A Pattern Language [Alexander+77], both vintage late 1970s, are frequently cited as inspiration for the contemporary software pattern ideas.
It's been 20 years since those ideas took shape, and Alexander is still around, still refining his ideas. While we've been focusing on patterns, and particularly on patterns specific to our domain, Alexander has explored deeper structures and their relevance to patterns and to beauty. His next major work, The Nature of Order--several thousand pages in four volumes--is on the horizon. In one way, Alexander has come a long way in 20 years as he has tied ideas together in a comprehensive theory. But most of what Alexander has done in those 20 years is learn to emphasize aspects of design that one can find in the older works, but which most readers choose to gloss over.
In Nature of Order, Alexander focuses on geometry. One view of architecture takes it to be the art of carving out space (not creating space, as the space is of course there all along), and space is all about geometry. Almost all of Alexander's patterns are about space and geometry, a fact often lost on contemporary software pattern practitioners. More generally, the concept of "space" has eroded in contemporary society since the Beatnik subculture of the previous generation understood it well and held it dear. What, exactly, does "space" mean in software? We touched on the importance of space a bit in my January column [Coplien98a]. In this column, we explore Alexander's more recent work and its relevance to software in more detail.
The foundations of classic architecture are aesthetics, utility, and durability. Alexander's patterns touch on all of these, but they seem to focus on utility and aesthetics more than durability (though some earlier patterns arguably work for the longevity of an ecosystem, and the latter patterns address durability in some detail). Our own software patterns, most notably the GOF patterns [GOF95], seem to focus on durability--what we call maintenance. Our community talks a lot about aesthetics, but aesthetic concerns are often lost on the patterns themselves.
Alexander is preoccupied with aesthetics, partly because some of his early experiments with patterns didn't generate the beauty he anticipated. Some of the lack of beauty he ascribes to issues of process: building codes, restrictions on funding models and mortgages that discourage piecemeal growth, zoning restrictions, and so forth. He resurrects this level of process as a conscious focus in Nature of Order. He was vaguely aware of the importance of process in Timeless Way ("The pattern is ... both a process and a thing; both a description of a thing which is alive, and a description of the process which will generate that thing", [Alexander79], p. 247), but he learned that it needed to be given greater focus if construction was to achieve aesthetic results.
But some of the lack of beauty he ascribes to simple geometric considerations. These, too, relate to a process problem, but it's a process problem at a finer level. A good process can't simply follow a collection of patterns forward, but must be guided by a concern for overall wholeness. Alexander uses the term "wholeness" often in Nature of Order, in a way that has echoes of "Quality Without a Name." Wholeness is, in large part, about aesthetics.
One liability of the contemporary architecture process is the architect, the self-appointed judge of aesthetics. By pronouncing beauty to be subjective, accessible only to selected artisans, architects can guarantee themselves a livelihood. Alexander maintains that beauty is in fact objective and has been held as such throughout most of history--until the onset of the industrial era [Grabow83]. But Alexander is not alone in this vein of contemporary thought; there are some sociologists who hold that there are at least some universal aspects of beauty that transcend culture:
Cultures do, of course, differ in their standards of physical beauty. But the differences are far fewer than scientists initially assumed. The main cultural differences center on whether relative plumpness or thinness is valued. In cultures that have relative food scarcity, plumpness tends to be more valued; in those with greater abundance, relative thinness is valued. Nonetheless, the physical cues to youth and health are seen as physically attractive in all known cultures that have been studied. In no known cultures do people perceive wrinkled skin, thin lips, jaundiced eyes, poor muscle tone, and irregular facial features to be attractive. [Buss94]
Alexander's "rug experiment" ([Gabriel96], [Alexander93]) and much of his earlier research explored this phenomenon of objective beauty. He concluded that beauty owes strongly to geometric properties, and spent years validating the nature of those shapes and the relationships between them. He developed a theory of beauty that transcends architecture, other human crafts, and structures in nature, based on centers, structural features, and process.
A center is something that draws our eye as a focus. It could be the top of a column, the center of a geometric design, or a well-proportioned bit of space at the side of a room. Centers have at least one axis of symmetry, and are reinforced by the centers around them.
Structural features enhance and strengthen centers to increase the level of wholeness in a system. Alexander feels there are about 15 of them [Alexander97]. Here is a superficial description of each of the features (he also calls them properties) whose important subtleties go beyond the scope of this article, but that are elaborated in Nature of Order:
Process is the discipline of applying the transformations in design. The same process is applied over and over again: apply a structure-preserving transformation that most increases the wholeness of the system. You can increase wholeness by adding new centers, removing weak centers, or intensifying existing centers, doing each in a way that strives toward one or more of the structural features. It is in this process that beauty emerges in space, as Alexander feels is the only way it can.
We talk a lot about beauty in the pattern community, yet we haven't yet found many patterns we agree are beautiful. Some stand out a bit, like HOPP (we'll get back to that later). Why? It's because they concern geometry, space, and structure. They don't concern abstraction, at least not the kinds of abstractions we often capture in software patterns.
What corresponds to geometry for us?
I think it is the code itself. Many talk about the need for excellent interfaces and the benefits of separating interface from implementation so that the implementation may vary. But few people talk seriously about the quality of the code itself. In fact, most theorists are eager to lump it into the category of things best not discussed, something to be hidden from view so that it can be changed in private. But think of Alexander's remarks: The quality comes in nearly equal part from the artistry and creativity of the builder who is the one whose hands most directly form the geometry that gives the building its quality and character. Isn't the builder the coder? [Gabriel96], p. 68.
Some artisans are better than others at writing beautiful code. With patterns, we try to raise the level of maintainability, or habitability, or aesthetics, or whatever, of our code. But there's something deeper than patterns going on here. What can we learn as everyday programmers that will leave us more able to write beautiful code?
To Alexander, beauty is in geometry, and geometry has the nice property that it has the same units in each of its three dimensions. To him, patterns are about geometry, and software patterns should be concerned with the software equivalent of geometry.
Let's take a stab at what that might be, taking off from Gabriel's
statement that geometry is in the code itself. Consider the following
simple function definition:
The way we think about writing code, we might think of the major
structural elements like this:
Such pictures look good even for bad indentation. We should instead
be looking for the space that's carved out by the code:
This block of code forms Positive Space that is a Good Shape. But
these are just procedural indentation tricks: how about class-level
design? Most block-structured programs have Alternating Repetition of
text and data:
It's strange; John Lakos consciously recommends an analogous alternation of objects and procedures in large system design [Lakos96]. Maybe Lakos' layering is the object-oriented dual of block-structured programming. In any case, it's the same pattern at a different level of scale. As an aside, Lakos took a curiously prescient perspective in his book:
Developing a large-scale software system in C++ requires more than just a sound understanding of the logical design issues covered in most books on C++ programming. To be successful, you will also need a grasp of physical design concepts that, while closely tied to the technical aspects of development, include a dimension with which even expert software developers may have little or no experience. (From the Addison-Wesley web page for [Lakos96])
Classes can have Local Symmetry:
and Graded Variation:
We can go on and on. Alexander's geometric properties can easily be found in code and in low-level design constructs. Many of them can be found at larger scales as well, just as Lakos applies Alternating Repetition at the architecture level. If these properties exist at all these levels, and if they have to do with structure, then we should expect to find them in the software patterns that convey architecture and structure.
Gerard Meszaros' HOPP pattern [Meszaros1996] is one of the most frequently cited examples of a good pattern, not only in its form and presentation, but as an important design technique. Might we be attracted to it because of some deep beauty within it?
The pattern's forces start out:
Many computer systems are forced to be implemented across multiple address spaces for reasons of cost, size, physical distribution, disparity of programming environments, regulatory reasons, and so on. Sometimes these systems can be easily decomposed into objects that each live in exactly one address space.
It seems like we're taking one center and making two centers out of
it. For example, there may be a single center (class) PhoneCall to
start with. (I'll show the evolution of the design through pictures
because to do this pattern justice in code would take too much
space. You can see similar structure in the code--try it and
see. Also, it's important to note that the pictures that follow
aren't a design notation, but try to give a feel for the geometry of
But then, Gerard says,
Sometimes, however, a concept exists in both spaces...
This wording--note the present tense--tells the designer's
perspective both on "a concept" (singular) and "both spaces"
(plural). The designer starts with one center that contains two
latent centers; latent centers are a frequent topic of discussion in
Nature of Order. Drawing out those latent centers reinforces the
center that contains them with Local Symmetry:
Each of these is a Strong Center. The pattern's solution is:
Divide the object into two interdependent half-objects, one in each address space, with a protocol between them. . . . Define the protocol between the two half-objects such that it coordinates the activities of the two half-objects and carries the essential information that needs to be passed between the address spaces.
We can do this by adding a Boundary about each of the HalfCalls that
ties them together. That's the Protocol part of HOPP. The
transformation lends Local Symmetry to the larger center. The
Boundaries should tie the objects together so the two together have
the same feel as the original single PhoneCall object: Deep Interlock
As this pattern scales up (three-way call, multiway call, broadcast), we might see Echoes and other emergent geometric properties.
Pretty groovy, yeah?
I speculate that one's ability to carry out this exercise, striving for Alexander's 15 properties in any pattern, will vary in success to the degree the pattern "feels like" a good pattern. Try it and see.
Those are the structure-preserving transformations that might lead to HOPP. What was the process that Gerard's predecessors and colleagues applied to create HOPP? Not any design method, but initially by trial and error or ingenuity, and perpetuated by experience. HOPP is not only beautiful, but it's a structure with crucial business importance: that's what makes it a pattern.
Imagine a software design process based on centers that would lead the designer through the transformations we used to derive HOPP above. Some of the centers would correspond to patterns that are already known; some would not. Is such a process necessary for beautiful software? Alexander hints that it was for want of such considerations that the pattern-oriented buildings of the Mexicali project were "funky." And is such a process sufficient?
And need all patterns be beautiful? Need something be a configuration of strong centers to be a pattern?
When an architect designs a house, he or she must consider not only beauty, but utility and durability as well. These are the three pillars of classic architecture. The theory of centers seems to address beauty well, and with a stretch, we can think of it as somehow contributing to strong structure. But utility probably eludes this theory altogether.
As Alexander noted, not even beauty, utility, and durability are enough. There are grander issues of process, too. If the builder is incented by a conventional mortgage model, will the builder want to obtain as much funding to build as large a building at the outset as possible? It may be difficult to obtain funding for later piecemeal growth. Beauty alone doesn't drive design.
Let's revisit the questions in light of this perspective. First, it's clear that the theory of centers alone is insufficient as a design tool. To build beautiful software, do we need to look at centers and structure? The jury is still out on this. To answer this question, we are embarking on some experimental studies reminiscent of Alexander's "rug experiments." It's too early to say much about them at this early stage, but I'll keep you posted on results, and I welcome suggestions, inquiries, and reports of independently conducted experiments.
Need all patterns be beautiful? Must a pattern be a configuration of strong centers? A good pattern should lead to wholeness (the Quality), and one can't ignore beauty in that endeavor. Clearly, not everything in pattern form leads to beauty--you don't have to read too many published software patterns to figure that out. But I believe the best patterns do lead to beauty, and they may do so (this is the question of the experiment) by adhering to the theory of centers.
We can pose the question in a more general way by asking: what is the relationship between patterns and centers? I view patterns as stereotypical configurations of centers, centers that have specific relevance in a particular domain. Alexander calls them generic centers. HOPP is a good example. Patterns are therefore more specific, more limited, and less abstract than centers. But patterns encode knowledge, experience, and cultural context. They address beauty, but they also address utility and durability.
What are patterns, then? Perhaps they are for Alexander what they are by analogy for computer scientists: just a way to remember what we've forgotten about buildings so that when we set out to build towns and buildings, cottages and homes, paths and places to congregate, we don't forget the stuff we need to help create the centers, to give them life, give them the quality without a name, the being that emerges at last. [Gabriel96], p. 95.
Many of you may not yet be satisfied with the code-based answer to the question: "What corresponds to geometry for us?" Let's investigate the question again from a different perspective--the back-door perspective of process.
As mentioned above, process is a major consideration of Alexander's work, and it has both become more important to him and taken on a more visible role in his forthcoming works. Alexander talks about several different kinds of process ranging from municipal and social processes (mortgages, zoning) down to construction processes (the sprayed concrete style of construction he favors versus conventional stick construction, for example).
What corresponds to process for us?
If you haven't gotten beyond the knee-jerk reaction to answer something referring to ISO or the CMM, then you probably haven't been reading my research papers. But that's another matter to be easily put aside for now. Well, we can almost put it aside. There is a process-like series of activities that take place in the piecemeal growth of habitable software, though these activities rarely correspond to written process specifications. Can processes like these embed the decisions of "apply a structure-preserving transformation to the weakest center"? That's a tantalizing proposition, and we--as software designers--probably would like it that way. And I think this is what actually happens in the best green-field designs. Our coding forays and shufflings and rework lead to an emergent design. As a painter dabs a bit in this area of the painting and then that, very dynamically, so we flit around our code intensifying the centers, bringing the program to life.
Let's adopt a completely different perspective. Some of my friends have been trying to identify patterns in code. I don't hold much hope (and certainly much value) for efforts that try to reverse engineer patterns from static studies of code; if one could do that, then patterns would just be replicated modules, and that rubs against even Alexander's most basic ideas about patterns. But how about looking at the running program? There may be patterns there.
Dean Jerding [Jerding97] et al., among others, have been studying this phenomenon in code. They're looking for patterns in object-oriented programs. How would you recognize a pattern? If you think of a pattern as a set of collaborating classes--centers that closely reinforce each other--then you could see the patterns as recurring paths of execution through local clusters of objects. Using visualization techniques, it's easy to find Alternating Repetition in time. Figure 1 visualizes an object-oriented program execution. Classes are on the vertical axis, with pixel-wide vertical lines drawn from the source to destination class. Method selectors are color-coded. The picture evidences several (recurring) patterns of execution. These of course aren't generative patterns yet; by looking at the picture, you can't tell what they do or how to implement them. But they may point to generative patterns in the code; it's unlikely that they don't. They aren't GOF patterns, but, well, so what? Maybe we should call them "centers"... But you should easily be able to find an instance of the Iterator pattern using a dynamic technique like this, although it would be devilishly difficult to do it by static analysis of the code.
This is a funny kind of space; it's more in the time domain than in the domain of geometry. Is that essentially so, or is just an artifact of the programming paradigm? We've been talking about the object paradigm, which is still just a minor refinement of the Von Neumann computational model. In the functional and applicative paradigms, one more or less unrolls time into space. Languages like HASKELL and KRC are examples of this paradigm. In SASL, infinite series can be expressed in closed form; the language generates specific terms in the series as they are called for instead of pre-computing them all (it's much more efficient that way, so to speak).
Functional programming is bursting with geometry. If you're not familiar with functional programming, but you've programmed an analog computer, the two paradigms are almost identical. If you're not familiar with analog computers, well, then, trust me, there are styles of programming where the computational designs are very spatial in nature.
What is the process that generates these structures? If you're programming in SASL, then it's just the development process--you can see structures in the code that at some level are analogous to the structures in Jerding's pictures. If you're programming in C++, the patterns (the centers) come from the run-time process, the thing running on the computer. Now that's a much different paradigm of emergent behavior than the model of software development processes! Of course, a sufficiently insightful programmer, who can think well in terms of reflection, can conduct a development process that will lead to a run-time process that will lead to beauty in the centers of run-time behavior. Architects, after all, must do something like this. They build houses and neighborhoods that are static constructs, designed to support the dynamic relationships, Circulation Realms, and processes of life that go on there.
Ah, maybe this is why programming is hard.
And this isn't such a far-fetched idea. Doug Lea has told me that distributed processing in Java has opened up whole new pattern insights for him. Other favorite patterns, like the Pipes and Filters patterns in the POSA book [Buschman+95], are also very spatial because they're about distribution. Distributed processing is about distribution in, well, space: it's essentially much more geometric than our good old procedural programs and their kissin' cousins, object-oriented programs. That, too, is a tantalizing thought. What are the centers in a distributed program? In a parallel program? In a program that runs as a co-routine?
Hmm, HOPP is one of the most elegant patterns we have, and it, too, is about distribution. Maybe we're on to something here.
Earlier, we addressed the question: So you have beautiful code; is that enough? We answered: no, you need other disciplines. How important is structure?
Consider Brenda Laurel's work [Laurel93]. She views a theatrical production as a metaphor for a computer program. Using a program should be emotionally engaging, emotionally satisfying; using a program to accomplish some task should leave you feeling somehow fulfilled. You might feel tension, amusement, and catharsis. In the process of doing your task, you want to feel engagement with the computer--more specifically, with the computer program. That means that the human/machine interface shouldn't be an interface between you and the program inside the machine, but that it should depict the structure of the program inside the machine. Why? Because users try to build models of what's going on inside the machine, based on their interactions of the interface. If the interface isn't a model of the program, then the designer has to figure out the model the user will craft for the model of the program, and build the interface to that model; that in turn changes the user model, and... well, it's turtles all the way down.
So there's at least something to be said about the structure of a good program boding well for the structure of a good interface. You have difficulty separating the two. A number of pattern notables, most memorably Kent Beck, can frequently be caught claiming that structure, good or bad, always shows through. No interface can fully hide it. I count myself among those that believe this.
Another passing thought: should the geometry of an interactive program reflect the geometry of its human/machine interface?
And of course Conway's Law says that you'll find the structure of the program mirrored in the structure of the organization that built it. Giving good space to objects gives good "space" to the programmers who maintain them: independence of development, local control.
And good organization structure leads to good processes.
And good process leads to good geometry in programs.
Hey, man, maybe those Beatniks were right on.
When you write patterns, try to write them about structure; the best patterns seem to be about the geometry of the code. Write patterns in the context of a pattern language, with each pattern reinforcing the centers built by other patterns.
Many thanks to Brad Appleton for chasing down the Buss citation on objective beauty. A special thanks to Richard Gabriel whose recent work in applying Alexander's theory of centers to poetry helped hone my perspective of how centers apply to code. Thanks, too, to Dick for some comments and corrections to an early draft. Thanks to Gerard Meszaros for letting me expand on HOPP in this column. And a special thanks to Liping Zhao for many enlightening discussions on this topic.
ChiliPLoP is coming up, March 17-20 in Phoenix, Arizona; see you there. See you at EuroPLoP at Kloster Irsee in Germany, July 9-12.
Copyright ©1997 Lucent Technologies, Bell Labs Innovations. All rights reserved.