A Pattern Language for Pattern Language Structure. Tiffany Winn and Paul
Calder. School of Informatics and Engineering. Flinders University of South
Australia.
A Pattern Language for Pattern Language Structure Tiffany Winn and Paul Calder School of Informatics and Engineering Flinders University of South Australia PO Box 2100, Adelaide 5001, South Australia {winn, calder}@infoeng.flinders.edu.au
beautiful later, because of the finesse with which you handle it, but that the collection of patterns which lie in the language now are not enough to make it beautiful, then there is something deeply wrong with the language … So, the real work of any process of design lies in this task of making up the language, from which you can later generate the one particular design. You must make the language first, because it is the structure and the content of the language which determine the design. (Alexander 1979, pp.323-324)
Abstract This paper aims to help the writers of pattern languages build better pattern languages. It focuses not on the esthetics of pattern languages, but on their structure: how patterns work together to build a system. The paper assumes that a pattern language is a designed system and, therefore, theory about system design and evolution underlies the language. In particular, the process of symmetry breaking has long been recognized as a means of analysing the processes by which natural systems form and evolve, and is used as a basis for this language. The pattern language identifies six patterns: Clustering of Related Forces, Piecemeal Growth, Local Symmetries, Cross Linkages, Local Repair, and The Void. Multidisciplinary examples are included with each pattern to verify that the fundamental theory is, in fact, fundamental.. Keywords: pattern language, symmetry, symmetry breaking, design, software design, C++ idioms.
1
Introduction
This paper presents the beginnings of a pattern language for building a pattern language. The main assumption is that it is valid to treat a pattern language as a designed system. The fundamentals that underlie pattern languages can then be used to build a pattern language that articulates the process of building pattern languages. In a discussion example related to garden design, Alexander points out that a pattern language is, in fact, a designed system: … the design of the garden lies within the language for the garden. … We tend to imagine that the design of a building or a garden takes a long time; and that the preparation for the process of design is short. But in the process where the language plays its proper part, this gets reversed. … Essentially, this means that the language which you have prepared must be judged as if it were itself a finished garden (or a finished building). … … if you think of the language merely as a convenient tool, and imagine that the garden of the building you create will become
Copyright © 2001, Australian Computer Society, Inc. This paper appeared at the Third Asian Pacific Conference on Pattern Languages of Programs (KoalaPLoP 2002), Melbourne, Australia. Conferences in Research and Practice in Information Technology, Vol. 13. James Noble and Paul Taylor, Eds. Reproduction for academic, not-for profit purposes permitted provided this text is included.
It is on this basis that we argue it is valid to treat a pattern language as a designed system. The Pattern Language for Pattern Language Structure seeks to articulate the process of building pattern languages for system design. Those pattern languages in turn articulate the process of building physical systems, and can thus be used in building such systems, as shown in figure 1. Further, patterns and pattern languages are structural. Alexander notes that a pattern is "both a process and a thing" (Alexander 1979, p.247): it focuses on both design process and design structure. A pattern language is also structural, and more powerful: it is "a collection of patterns that build on each other to generate a system. A pattern in isolation solves an isolated design problem; a pattern language builds a system." (Coplien 2000a, p.19) The structures in the pattern language for pattern language structure will, therefore, be able to be seen both in pattern languages, and in physical systems generated from pattern languages. Both examples from pattern languages and systems in a range of domains are hence used to illustrate the patterns. Key issues addressed by this pattern language include the following: •
how to add structure to a pattern language.
•
how to maintain stability in a pattern language over time.
These issues are important because they are key issues from the point of view of building patterns languages for complex systems, where those systems function effectively, over a long term, in a dynamic environment. They relate both to how patterns work together, and to the structural properties of systems generated through pattern languages built from this pattern language.
Pattern Language for Pattern Language Structure
Pattern Language for Biological Beings
Biological Being X
Pattern Language for C++ Programs
Pattern Language for Houses
C++ Program 1 House A
Being X
C++ Program 2
Biological Being Y
House B
Being YBeing Biological Being Z
C++ Program 3
House C
Figure 1: the pattern language for pattern language structure helps build pattern languages for system design, that in turn help build physical systems
A further assumption underlying this pattern language is that system designers can learn from the patterns and systems of nature. Systems in nature are inherently stable: “Natural systems must be stable; that is, they must retain their form even if they’re disturbed.” (Stewart and Golubitsky 1992, p.14) So system designers who seek to build systems that are stable (behave predictably) and yet able to change (to adapt in a dynamic environment) can therefore build better systems by learning from the patterns and systems of nature. As symmetry breaking is one explanation of the processes by which systems in nature form and evolve, system designers can also benefit by understanding the role of symmetry and symmetry breaking in nature, and in their systems.
2
Symmetry Breaking
Symmetry means invariance in the face of change. A five-pointed starfish, for example, can be rotated by onefifth of a full turn about its center and it will still look the same. The appearance of the starfish is invariant despite the rotation changing its position. More formally, a symmetry of an object "is a transformation that leaves it apparently unchanged." (Stewart and Golubitsky 1992, p.28) What it means to be unchanged is dependent on how sameness, or equality is defined in the given context. Further, it is not only in the context of geometric objects that symmetry can be defined: Rosen defines symmetry as follows: Symmetry is immunity to a possible change. When we do have a situation for which it is possible to make a change under which some aspect of the situation remains unchanged, i.e., is immune to the change, then the situation can be said to be symmetric under the change with respect to that aspect”. (Rosen 1995, p.2)
Mathematically, symmetries are defined in terms of group theory: the set of symmetry transformations on an object forms its symmetry group. A group is a closed system of transformations. The result of applying any two transformations in a group in succession is thus always equivalent to a single transformation already in the group. (Stewart and Golubitsky 1992) In the case of the starfish, its symmetry group consists of five rotations (no rotation, and rotation by one-, two-, three-, and four-fifths of a turn) and five reflections about a line through each of the arms. Combining any two of these transformations simply results in one of the original ten transformations in the group. For example, rotation by one-fifth of a turn and then two-fifths of a turn is equivalent to rotation by three-fifths of a turn. (Stewart and Golubitsky 1992) Symmetry breaking could perhaps better be called symmetry sharing, because it refers to the way that symmetry is redistributed when forces cause it to no longer be sustainable. Perhaps the most important of the physical laws governing how symmetry breaks is Curie's Principle, which states that when a system is transformed, symmetry is preserved: symmetry in the cause is preserved in the effect. So symmetry in nature should always be preserved. Sometimes, though, that is not what seems to happen. Consider what happens when a droplet of milk falls into a glass, as shown in figure 2. The droplet of milk is the cause and the splash the effect. Before falling into the glass of milk, the droplet of milk is round, and so has spherical symmetry: it is symmetric for any rotation about its center. When the droplet falls into the milk, forces, such as the surface tension of the milk, mean that it cannot maintain its round shape. The new shape that forms – the crown-like shape – no longer has spherical
symmetry. So it seems as though symmetry is not preserved. In fact, Curie’s principle reflects mathematical possibility rather than actual, physically realized states: the set of all crowns that the milk drop could potentially form when it makes a splash - including those, for example, underneath the surface of the milk in the glass - has full rotational symmetry. The actual crown that forms has a subgroup of full rotational symmetry: it has some of the same symmetries as the drop, but probably not all, and no new symmetries that the drop doesn't have: When symmetry breaks, the symmetry of the resulting state of the system is a subgroup of the symmetry group of the whole system. So symmetry-breaking is a change in the symmetry group, from a larger one to a smaller one, from the whole to a part. (Stewart and Golubitsky 1992, p.52)
and maintain stability when forces, such as a greater need for efficiency, mean that the software needs to change. Analysing symmetry in software, and how best to redistribute it in accordance with the symmetry breaking seen in nature, may give clues as to how to change software and yet maintain its stability. In the software domain, unlike in nature, there is currently no formal basis for symmetry-based analysis: that is, there is no established analysis connecting symmetry observed and defined at an informal level with the formalized notion of symmetry, symmetric transformations, and symmetry groups in mathematics. Any attempt to analyze symmetry in software must thus be either informal or attempt to establish such a formal basis. Work attempting to establish such a formal basis includes Coplien and Ziao's (2001) ongoing work on symmetry and software patterns. Coplien (1998, 1998a) has also informally analysed symmetry in software and software patterns.
3
Related Work
The way that systems form and evolve has been the subject of much research. This section highlights selected work in a range of areas relating to that theme, including pattern languages, symmetry breaking in nature, understanding symmetry in software, and design theory and practice. The C++ Idioms Language (Coplien 2000) and the Half-Object Plus Protocol (HOPP) pattern (Meszaros 1996) are also summarized here since they are used extensively as examples in the following section.
3.1 Figure 2: a milk drop and the splash it forms when landing in a glass of milk
So symmetry is preserved. Stewart and Golubitsky articulate an extended Curie principle as “a symmetric cause produces one from a symmetrically related set of effects”. They further point out that this phenomenon, where the actual, physically realized effect breaks the symmetry of the potential, is called symmetry-breaking, and it leads to the formation of patterns: This paradox, that symmetry can get lost between cause and effect, is called symmetrybreaking. In recent years scientists and mathematicians have begun to realise that it plays a major role in the formation of patterns. … From the smallest scales to the largest, many of nature’s patterns are a result of broken symmetry; and our aim is to open your eyes to their mathematical unity. (Stewart and Golubitsky, 1992, p. xviii) Software patterns represent tried and true solutions to recurring problems. Many software patterns may also break symmetry and thus show how to transform software
Pattern Languages
Architect Christopher Alexander's earlier work (1977, 1979) was foundational in developing the concept of a pattern language as a means to articulate the process and structure by which systems evolve. Alexander developed a pattern language for architecture that identified recurring, good structure in architecture and could be used to generate such structure. Eventually, however, Alexander found that pattern languages on their own are not sufficient to generate good structure (Coplien 1998). In Alexander's context, good structure means beautiful buildings, and his quest to build beautiful buildings led to his more recent work on the nature of order (1996, 1996a). This work is more broadly focused than his earlier work and provides context for using pattern languages as part of a process of generating structure. It is important to note that beauty is not about image, nor is it opposed to functionality, but rather beauty and functionality are one and the same when understood correctly. Both are inherently tied to structure, which leads Alexander to address two fundamental questions: "What is good structure?" and "How can humans generate good structure?" While Alexander's primary interest is in architecture, the implications of his work are much more broader in scope and relevance. In Alexander's terms, good structure is that which makes whole. It is objectivein the sense that it is so consistently recognized as such, across wide ranges of people, that it can be considered universal. It is identifiable in terms of
the presence and strength of centers (Alexander's term for fundamental building blocks) in a system. Alexander identifies fifteen key properties that help to build and strengthen centers: the degree to which these properties are present in a system is a measure of the strength of the system's centers and thus the goodness of its structure. Alexander further argues that good structure is only be generated by a process that can be categorized as an unfolding process. Such a process is one in which growth is incremental and always seeks to benefit the whole, in which there is continuous feedback about possible directions for growth, and in which the unpredictable nature of that growth is accepted and valued. Traditional cultures were inherently more conducive to unfolding processes: apart from anything else, change happened at a much slower rate. But Alexander argues that unfolding can happen in the current cultural context, and outlines the fundamental process, an unfolding process suitable to the creation of good structure in the current cultural context. In Alexander's view, pattern languages are necessary to the development by humans of good structure because they provide contextual, cultural information necessary to strengthen centers. Alexander further argues that if a pattern language is to be capable of generating good structure, his fifteen properties should be present in the language to a high degree, and the language should embody an unfolding process of design.
3.2
Symmetry Breaking
Stewart and Golubitsky (1992) analyze symmetry breaking in natural systems as a way of understanding how those systems form and evolve. They use examples such as the milk drop forming a splash and dew drops forming on a spider web. When a droplet of water falls on a web, it doesn't spread evenly like a cylinder around the thread, with the same symmetry as the thread, because the surface tension of the water compresses it along the direction of thread. Like a very tall stack of books tied with elastic, the fully symmetric state is thus unstable, and the water buckles at various points. Yet, if the translational symmetry of the thread is to remain in some form, the water must buckle at regular intervals, which it does, and if the reflectional symmetry is to remain in some form, then the dew drops must be bilaterally symmetric, which they are. The original thread had full translational symmetry; the thread with dew drops has translational symmetry at regular intervals. Similarly, the original thread had full reflectional symmetry; the thread with dew drops has reflectional symmetry at regular intervals. The thread with dew drops has some, but not all, of the symmetries of the original thread, and no new symmetries: the symmetries of the thread with dew drops are a subgroup of the symmetries of the original thread. Stewart and Golubitsky highlight many such examples of symmetry breaking in nature, and argue that symmetry breaking plays a significant role in the formation of patterns in nature, and thus in how systems in nature form and evolve.
Coplien and Ziao (2001) have attempted to apply symmetry formalisms to the software domain. They propose a formalism for software patterns that is grounded in group theory and concepts of symmetry, and argue that several common language features can be formally classified as symmetries because they meet the mathematical requirements for such a definition. Coplien and Ziao go on to analyze the symmetry in programming language concepts such as types and functions, and investigate how a range of patterns might break such symmetry. Their work is ongoing and represents an initial attempt to analyze symmetry in software.
3.3
Design Theory and Practice
Winograd and Flores (1986) explore design theory with particular reference to the design of computer technology. They first explicitly outline the philosophical, language, and thinking traditions or patterns that implicitly underlie much of western thought. They go on to explore how these usually assumed and implicit cultural traditions influence the kind and effectiveness of the computer technology we develop. The conclusion they draw is that some of these patterns/traditions do not help us build "good" computer technology, because the assumptions on which they are based are outdated, inaccurate or inappropriate for the area concerned. Other philosophical and language traditions that present different, and perhaps more correct assumptions are explored and future directions for the design of computer technology suggested. One of the key points that Winograd and Flores make is that successful design is not about anticipating every possible change. Rather, successful design requires identifying the fundamental structure of a domain and recognizing that that structure governs the kind of change likely to occur. A successful design is therefore one that can evolve within that structure: The most successful designs are not those that try to fully model the domain in which they operate, but those that are “in alignment” with the fundamental structure of that domain, and that allow for modification and evolution to generate new structural coupling. As observers (and programmers), we want to understand to the best of our ability just what the relevant domain of action is. This understanding guides our design and selection of structural changes, but need not (and in fact cannot) be embodied in the form of the mechanism. (Winograd and Flores 1986, p.53) So, if systems are characterized by both symmetry and symmetry breaking, then system designers need to be able to build structures that express both symmetry and symmetry breaking in order for their systems to be effective; that is, in order for their systems to express the intent of the designer. (Coplien 2000b) Foote and Yoder (2000) use their pattern language Big Ball of Mud (BBOM) to analyze the haphazard processes by which much software is built. They argue that much effective software is expediently and haphazardly
structured, and explore the forces that bring about such an approach to software development and the management of such software. The main question BBOM explores is “Whether it produces a good result or not, what actually happens when software is built?” In contrast, we have addressed the issue of what we can learn from nature that will help in building stable, adaptable software. Refactoring is a technique for improving the internal structure of code without changing its external behavior. It uses small, known, incremental changes to reduce the short-term cost of making the effort to write good code. Fowler (1999) defines a refactoring as "a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior" and also notes that the term is used slightly differently when used as a verb: "Refactor (verb): to restructure software by applying a series of refactorings without changing its observable behavior." Refactoring is similar to this work in several ways: it is a design technique grounded in actual, designed artifacts; it focuses on small-step, piecemeal growth; and it is based on a view of the design process whereby design occurs continuously during development, rather than a good design being a necessary precursor to good code. Refactoring differs from this work in several ways: it focuses almost exclusively on the practical aspect of design rather than on any underlying design theory; its main focus is on applying particular refactorings, rather than how different refactorings fit together and provide a broader picture of software design; and it explicitly distinguishes between adding functionality to code and rearranging existing code, and defines refactoring as the latter and not the former.
3.4
Relevant Examples
The C++ Idioms language (Coplien 2000), based on idioms drawn from (Coplien, 1992), guides the building of an inheritance hierarchy in C++, with particular focus on algebraic types. Key issues in building such a hierarchy include efficient and effective memory management, placement of algebraic operations in the hierarchy, and implementation of abelian operations without using multiple inheritance. The base patterns in the language are Handle/Body (HB) and Concrete Data Type (CDT). HB splits a class into interface (handle) and implementation (body) classes, providing the convenience of scope-based memory allocation where the entity concerned is not in (program) scope. CDT shows how to effectively manage memory allocation and deallocation when object lifetime does not follow program scope. Other patterns build on these base patterns to address further issues of memory management. Algebraic Hierarchy (AH) outlines how to distribute algebraic operations in the hierarchy. The patterns below AH enable heterogenous addition to be implemented within such a hierarchy. The approach used is for the add method in each subclass to deal only with operands of its own subclass (Homogenous Addition), for each subclass to know how to promote itself to the next class up the hierarchy (Promotion Ladder), and then for operands of different type to be promoted to the same
type before adding (Promote and Add, NonHierarchical Addition). The Half-Object Plus Protocol (HOPP) pattern (Meszaros, 1996) points out that distributed computer systems must often be implemented across multiple address spaces. Such systems can sometimes be decomposed into objects that live in exactly one address space, but other times a concept exists in more than one space. For example, in designing a distributed call processing system, the concept of "phone call", embodied in, for example, the capacity to establish and terminate a phone call, needs to exist in multiple address spaces. Implementing a concept that exists across address spaces can be done in a number of ways. As one example, all but the most basic processing could be done in one address space. As another example, a separate object and protocol could be designed for each address space, and then interaction across address spaces managed by another protocol. HOPP implements a concept across multiple address spaces by transforming the relevant object into two "halfobjects" plus protocol, one half-object in each address space. Each half-object implements “whatever functionality is required to interact efficiently with the other objects in that address space” (Meszaros 1996). The protocol between half-objects is defined so that it coordinates their activities and passes only essential information between address spaces.
4
The Pattern Language
We have identified the following six patterns as part of the language. Each pattern begins with a patlet that conveys the intent of the pattern, followed by Context, Problem, Forces, Solution, and Rationale sections. Each pattern then has examples from biological, architectural and software systems. These multidisciplinary examples are included to validate that the fundamental theory is, in fact, fundamental: that is, the underlying theory does apply across a range of domains. The examples also help explore the design issues addressed by the pattern language. Given that the main assumption of the paper is that a pattern language can be treated as a designed system, and that it seeks to be a language that can be used to build pattern languages, pattern language examples are also included as part of each pattern.
Clustering of Related Forces If there are too many forces to think about all at once Then cluster related forces and think about the clusters.
Context: Considering many interrelated forces simultaneously. The system of forces likely lacks structure.
Problem: How to balance many interrelated forces to build a stable system. OR
How to coordinate a system in which there are many interrelated forces.
Forces: Too much information to be processed simultaneously. The system structure needs to be better articulated for the system to be stable.
Solution: Cluster related forces.
Rationale: Building a stable system requires understanding the forces acting on that system and how they interact. When there are many such forces, they and the interactions between them are likely too complex for a designer to grasp simultaneously. The design problem therefore needs to be subdivided into smaller problems. Further, the design problem needs to be subdivided in such a way that it matches the subdivisions of the system in its domain. This can be achieved by both minimizing interactions between separate subdivisions and maximizing interactions within subdivisions: i.e., by clustering related forces. (Alexander 1964)
Example (C++ Idioms Pattern Language): Patterns in a pattern language represent subdivisions of the design problem into smaller problems. As such, each pattern is a clustering of related forces, where those forces are in the domain of systems being implemented with the language. Developing a pattern language thus requires identifying key structures in the domain of implementation and articulating those structures as patterns that build on each other. Connections within patterns ought to be maximised and connections between patterns minimized. Memory management is a key issue addressed in the idioms language. The Handle/Body pattern (HB) clusters forces related to convenient use of memory. It splits a class into interface (handle) and implementation (body) classes, creating a situation where many handles can potentially refer to the one body. Counted Body (CB) resolves this situation: it suggests adding a count to the body object that keeps track of the number of handles. CB thus clusters forces related to memory allocation in an HB context. It assumes that the body code can be modified. Detached Counted Body adds to a CB context the capacity to manage multiple handles where the body code is not accessible. Each of the above patterns resolves a collection of related forces and creates new forces. The patterns build on each other to generate a solution. Further, the patterns represent precise chunks of a problem/solution and the interconnections between them are clear and simple. This may indicate that the patterns individually and as a group cluster forces well, but such a hypothesis cannot be easily verified, as is explained in more detail in the architectural pattern language example below.
Example (software system): A system designed with HOPP is designed such that whatever can be done locally is done locally: half-objects minimize communications with other address spaces even if it means duplicating functionality, and the protocol between half-objects is defined so that only essential information is passed between address spaces. A system designed with HOPP thus minimizes interactions between separate subdivisions (only essential information is passed between address spaces), and maximizes interactions within subdivisions (all that can be done locally is done locally): it clusters related forces.
Example (architectural pattern language): Alexander notes that in understanding the forces that define a pattern, "we must rely on feelings more than intellect". (Alexander 1979, p. 286) He is precise in what he means by this – there is no simple rule with which to verify that a pattern does indeed cluster and then resolve related forces. Confirming the validity of a particular clustering of forces is, therefore, not simply a process of abstract argument, but requires a more intangible mix of theory and practice. In A Pattern Language (Alexander 1977), Family of Entrances clusters forces related to easy identification of entrances: it says that entrances that humans would classify as part of a group ought to be easily recognizable as such. Main Gateways clusters forces related to marking boundaries: it says that entrances that cross boundaries with important human meaning should be marked with "great gateways". The two patterns are related, but their connection is hard to articulate, and that is a clue that some forces still need to be dealt with. A pattern (a clustering of forces) is therefore probably missing that connects the two patterns. In fact, Family of Entrances and Main Gateways are not directly connected in APL, but connected by means of an Entrance Transition. Entrance Transition identifies the tension arising out of the difference in peoples' behavior in a public versus a private place. The forces that it clusters, or brings together, have to do with that behavior: that people tend to wear some degree of mask for more public behavior, that people relax that mask to a greater degree in more private places, and that relaxing that mask needs space and time to happen. Entrance Transition allows these forces to be resolved. Entrance Transition thus helps to minimize links between patterns in the language: it helps to build a structure that more accurately reflects the structure of buildings and the way people use them. The relationship between Main Gateways and Family of Entrances is now clear: this is a clue that each of their clusterings of forces is more accurate.
Example (architectural system): A common epigram of modern architecture is "form follows function": the form of buildings should be designed around their function. The forces being considered are to do with the functions of different spaces in a building: for example, in a house, forces might include the need for space to eat, to cook, to sleep, to wash, to dress, to store clothes, to sit and relax, and so on.
Alexander's pattern Structure Follows Social Spaces (1977) clusters or groups together forces that relate to similar building function: so, for example, forces relating to eating and cooking would be clustered. The physical building is then structured around those clusters of forces: for example, a kitchen is designed to cater for food preparation, consumption, storage, and so on.
Example (biological system): A creature that finds itself in a situation of immediate danger responds by releasing the hormone adrenalin into the bloodstream. Forces in this situation include the need for more light, the need for more oxygen, and the need for more energy. Each of those forces needs a different response: the need for more light is addressed by dilating the pupils of the eyes, the need for more oxygen is addressed by dilating the bronchial tubes, and the need for more energy is addressed by the liver converting glycogen to glucose. The heart rate is also raised in response to the need for more oxygen and energy. But in a situation of immediate danger, there is not time for each of these forces to be separately addressed, by the appropriate system in the body. Instead, the forces are clustered (the clustering is functional) and the nervous system, which plays a coordinating role in the body, releases the hormone adrenalin into the bloodstream. Release of adrenalin into the bloodstream simulates the conditions that each system needs to respond to and thus enables the system to respond simultaneously to all the above forces.
Piecemeal Growth If new structure needs to be added to the system Then add it gradually, piece by piece, evaluating the effect of the change on the whole.
Context: New structure needs to be added to an existing clustering of forces.
Problem: How to add the new structure and yet preserve existing system structure as much as possible, so that overall system stability is preserved.
Forces: Change does not happen in isolation: change to one part of a system will affect other parts. A system will need to evolve over time: new structure will need to be added. Maintaining overall stability may result in a particular solution being suboptimal.
Solution: Make changes one at a time, based on past experience, and with the opportunity to adjust and/or reverse changes if their impact on the whole is unacceptable. (Alexander 1996a)
Rationale: Awareness of the impact of local change on a system as a whole is critical because in an interconnected system, change to one part of a system inevitably affects other parts of the system. Piecemeal growth helps build stable systems for a number of reasons. Change is based on what has worked in the past rather than what is anticipated to happen in the future. Change is incremental and thus gives an opportunity for feedback, with the effects of small changes able to be studied before other changes are made, and changes altered if necessary. Further, such incremental change implies a willingness to live with unpredictability: to resist defining a priori the nature of major change, and let that change unfold step by step. Alexander (1996a) argues that an unfolding process is, in fact, necessary to the development of good structure in a system.
Example (C++ Idioms Pattern Language) Each of the patterns in the idioms language builds incrementally on other patterns in the language. Changing the pattern language by adding a pattern is thus always an incremental change to the language. Evaluating the effect of such a change on the whole requires identifying the connections between the pattern being added and other patterns in the language. The stronger the clustering of each pattern and, hence, the lesser the interactions between patterns, the more the effects of adding a pattern to the language will be localized. For example, Handle/Body Hierarchy (HBH) shows how to incorporate a Handle/Body (HB) structure into an inheritance hierarchy. HBH assumes the existence of HB and builds on its structure. Algebraic Hierarchy (AH) in turn builds on HBH: it shows how to distribute algebraic operations in an HBH structure. Any change to HBH could potentially effect both HB and AH.
Example (software system): Robert Hanmer (1999) has written a pattern language for traffic congestion. It focuses on how to evolve a network to manage situations where network load exceeds resources. The language articulates common strategies used successfully by telecommunications switching networks to manage congestion. Some of the patterns in the language Hanmer classifies as implementing expansive controls: "Expansive controls allow the system to use additional resources not available to call processing under normal conditions. This expands the possible actions that the system may take." For example, Automatic Out-of-Chain Routing (AOCR) deals with network congestion by adding to the existing network routes not normally part of the network. Patterns like AOCR facilitate incremental growth in systems by showing how to make small additions to the system when necessary. This ability to adapt incrementally increases system stability: in the case of AOCR, it levels the system load so that the system's performance level is more predictable.
Example (architectural pattern language): A pattern language is a continually evolving artifact. As it is being developed, new patterns will be added: We must … invent new patterns, whenever necessary, to fill out each pattern which is not complete. (Alexander 1979, p.323) Whenever a pattern is added to the language, the effect of adding that pattern on the structure of the whole language must be considered: Each pattern … is supported by other patterns: the larger patterns in which it is embedded, the patterns of the same size that surround it, and the smaller patterns which are embedded in it. This is a fundamental view of the world. It says that when you build a thing you cannot merely build that thing in isolation, but must also repair the world around it, and within it, so that the larger world at that one place becomes more coherent, and more whole … (Alexander 1977, p.xiii). Adding patterns to the language must also be done in small steps. While Alexander suggests that when using the network of his language, you should begin with larger patterns and work through to smaller patterns, he points out that the larger patterns cannot be created in one fell swoop, but must be developed piecemeal: It is essential to distinguish those patterns which are the principal components of any given pattern, from those which lie still further down. … And this process of defining the principal components of a given pattern is what finally completes it. … When every pattern has its principal components given by the smaller patterns which lie immediately below it in the language, then the language is complete. (Alexander 1979, p.321-322) For example, Circulation Realms suggests identifying the nested system of realms, from largest to smallest, that make up a building. Those realms should then be marked in some way, so that people using the building can easily orient themselves inside the building. But Circulation Realms of itself does not give enough of an idea of how to build a building with circulation realms, so the pattern needs to be elaborated with other patterns. The largest entrances of Circulation Realms ought to be Main Gateways, and other groups of entrances should each form a Family of Entrances. A Family of Entrances, though, needs a Main Entrance and its entrances need Entrance Transitions, and so on. Identifying Circulation Realms as a pattern in the language thus implies the addition or existence of many other, finer-grained patterns that make it up. This forces the language to grow incrementally. Circulation Realms must also be evaluated to see whether it fits well with other patterns in the language, particularly those that it ought to lie directly
underneath. Adding a pattern to the language is thus a process of piecemeal growth: the change is done incrementally, and its effect on the whole evaluated at each step.
Example (architectural system): In his book How Buildings Learn (1997), Stewart Brand argues that slow, small step growth – piecemeal growth – is what makes a building grow gradually better rather than gradually worse over time. Piecemeal growth is not just healthy for individual buildings. Brand argues that much wholesome evolution of cities can be explained by the persistence of site: in other words, by the fact that property lines and thoroughfares in cities do not change even when, for example, hills are leveled and waterfronts filled in. Brand also points out that most building design is vernacular and vernacular design is inherently piecemeal.
Example (biological system): Pandas do not possess a thumb, yet they need some kind of similar implement in order to strip bamboo, their primary source of food. Over many years, pandas have developed a substitute for a thumb out of their paw. The thumb substitute has evolved gradually, as a part of the paw becoming longer and more and more distinct from the rest of the paw. The thumb substitute may not work nearly as well as a proper thumb, but it is an example of a series of structure preserving transformations maintaining stability in a system, producing a solution that may not be optimal but is workable.
Local Symmetries If the system structure is still too coarse-grained Then elaborate it with finer structure by breaking symmetry in the domain of implementation.
Context: Development of a system design component for which the implementation is not immediately obvious.
Problem: How to articulate system structure in more detail.
Forces: Articulation of system structure must have reached a certain level of detail in order to be able to implement it. Parts of the system need to become specialized for particular tasks. Local symmetry, rather than global symmetry, is critical to a system's stability.
Solution: Replicate and refine grosser structure in the system design by identifying symmetry in the system being built and elaborating the design so that the symmetry in the implementation is transformed into local symmetries by symmetry breaking.
Rationale: As a system develops, parts of the system need to become specialized and different from each other. If, however, the established grosser structure is good it should be preserved as the system is built. Further, global symmetry is not stable: a system needs more fine structure – more local symmetries – to be stable. Elaborating grosser structure with finer structure by breaking symmetry transforms the system in a structure-preserving way and thus increases system stability: global symmetry is redistributed locally, so that the symmetries of the transformed system are a subgroup of the symmetry group of the original system, and the increase in local symmetries increases stability. In addition, change in nature works by creating local symmetries. (Stewart and Golubitsky 1992) Making sense of system structure therefore requires an understanding of system symmetries; patterns should work by breaking global symmetries to create local symmetries.
Example (C++ Idioms Pattern Language): Patterns in the idioms language that create local symmetries in the system being built include Handle/Body, Detached Counted Body and Homogenous Addition. Handle/Body splits a design class into two implementation classes, one of which is the interface (Handle) and the other the actual implementation (Body). It thus creates local symmetries in the system being built: the Handle and Body still represent one conceptual entity (and they are linked in the implementation structure), but the conceptual entity is now composed of two smaller entities. Detached Counted Body (DCB) shows how to implement a count for the number of handles to a body without modifying the body code. It separates the count and body in CountedBody (CB), but links the two by splitting each handle into two parts, one of which acts as a handle for the body and the other a handle for the count. DCB thus elaborates on CB by creating local symmetries in the system being built: the handle from CB remains as one, whole entity, but now has two parts, each of which is like the original whole. Homogenous Addition builds on Algebraic Hierarchy. Algebraic Hierarchy distributes responsibility for algebraic operations evenly among subclasses: for example, each subclass has an "add" method, rather than the addition operation being forwarded to a base class. Homogenous Addition further specifies that the add method in each subclass should deal with operands of its own subclass only, and thus not have to deal with type conversions required in heterogenous addition. Each add method is thus a local symmetry, and hence Homogenous Addition elaborates on Algebraic Hierarchy by creating local symmetries in the system being built.
Example (software system): HOPP represents a transformation of a system: a concept that has been implemented in exactly one address space moves to be implemented across two or more address
spaces. The object implementing that concept is transformed such that it comprises two "half-objects" plus a protocol that manages interaction between the halfobjects. The protocol and half-objects together make up the HOPP object. In the original system, the relationship between the object in question and each of its client objects is the same: each of the client objects "sees" the given object in the same way, because all of the object's functionality is in the same place. This sameness of relationship between object and all client objects is a symmetry: the invariant is the relationship between object and client, and what changes is the particular client involved. This symmetry might be lost when a concept is split across object spaces, but HOPP preserves it, by redistributing symmetry inside the HOPP object to create local symmetries: each half-object is created as like the original as possible, even if that means duplicating functionality. Clients can interact with each half-object as if it were the original, whole object. When forces require a concept to be implemented across multiple address spaces, HOPP thus indicates how to change the system to allow the distribution, yet still preserve the symmetry of the original system as much as possible, by creating local symmetries. HOPP provides an implementation that preserves a conceptual symmetry of relationship between object and client, by creating local symmetries in the system implementation. (Coplien 1998, Coplien 1998a) Further, consider a distributed system in which the HOPP pattern is present. If the system needed to expand from, say, two to three sites, it could do so easily by transforming the existing HOPP structure from two halfcalls to three, and so on for further adaptation: the relationship between client and existing "half-objects" does not need to change, and the new client object relationship is the same as that for existing client/object pairs. It is this preservation of symmetry that enables this kind of incremental growth, by allowing the growth to be based on existing system structure. Warren Montgomery (1998) noted the importance of preserving symmetry in the context of development of telecommunications software: Making the model symmetric, if you can, leads to great simplifications. [A system I worked on] started out symmetric, no notion of originating and terminating terminal process, just terminal processes. The call protocols were all symmetric. This made it very easy to take the next step of going to multi-party calls … (Montgomery, 1998)
Example (architectural pattern language): In Alexander's A Pattern Language (APL) (1977), some patterns are refined – or, as Alexander often says, "embellished" - by other patterns. For example, Circulation Realms identifies the need to build buildings that allow people to orient themselves well, and suggests building into a building's structure a sequence of progressively smaller realms in order to facilitate orientation. Family of Entrances is one pattern that
refines Circulation Realms. Family of Entrances creates local symmetries in the architecture it generates: it suggests that multiple building entrances should be each be recognizable as a part of a group or "family" and therefore be similar in structure, look and feel. Family of Entrances thus elaborates on Circulation Realms by creating local symmetries in the system being built. Despite the need for multiple building entrances to look and feel similar, and to be placed in a way that creates local symmetries in the building structure, sometimes one entrance of a family functions as the main entrance to a building, while the others are alternate entrances. In order to make this difference in function clear the main entrance ought to be differentiated from the others. One way in which this can be done is to add to the main entrance so that it juts out beyond the building line. The positional symmetry of the family of entrances is then preserved, but the symmetry of look and feel is broken: the main entrance is thus both distinct from other entrances and still identifiable as one of a family of entrances. Main Entrance is thus a pattern that elaborates on Family of Entrances by breaking symmetry in the system being built.
Example (architectural system): In Building Complex, Alexander (1977) notes “… the more monolithic a building is, and the less differentiated, the more it presents itself as an inhuman, mechanical factory.” Alexander argues that it is important that building structures reflect the different social identities of people who use the buildings. In buildings that do so, a person’s experience of using the building is more likely to be positive, and their interactions with other people in the building more likely to be regarded as personal, rather than impersonal. Symmetry in a building should therefore be local, rather than global.
Example (biological system): As most biological organisms develop, cells become specialized for different tasks. Initially, cells simply divide and replicate. These cells are called “stem cells” because, at this stage of development, any cell has the potential to become any particular kind of cell. At some point, however, “stem cells” begin to specialize, and become either organ, skin and gut, or nerve cells. Each of those groups of cells then further specializes: for example, skin and gut cells specialize into cells for the skin, or cells for the lining of the gut. The transformation whereby stem cells specialize or "differentiate" can be viewed as creating local symmetries, because existing structure is replicated and refined, rather than being fundamentally changed: "The cells of the body differ in structure and function not because they contain different genes, but because they express different portions of a common genome." (Campbell 1996, p. 985)
Context: Developing the structural interconnections between parts of a system that solves a complex problem.
Problem: A simple hierarchical structure will not solve complex problems.
Forces: System structure needs to be in alignment with fundamental domain structure. (Winograd and Flores) Containment, or specialization is not the only kind of structural relationship in many domains.
Solution: Allow system elements to overlap or "cross link", rather than requiring elements to be either wholly contained in or disjoint from other system elements. (Alexander 1965)
Rationale: The structure of complex systems cannot be articulated in a simple, tree-like hierarchy, because elements of such systems sometimes overlap, rather than being either wholly contained in or disjoint from other system elements. Overlap is, in fact, an essential generator of complex structure and representing complex systems as simple, tree-like hierarchies is therefore inaccurate and potentially destructive. A better representation of a complex system is a semi-lattice, which allows its elements to overlap. The main constraint on a semi-lattice is that "when two overlapping sets belong to the collection [semi-lattice], the set of elements common to both also belongs to the collection". (Alexander 1965)
Example (C++ Idioms Pattern Language): The relationships between patterns in the idioms language are represented in a structural diagram (Coplien 2000) that draws an arrow from Pattern A to Pattern B where Pattern B builds directly on Pattern A. These arrows illustrate the cross linkages existing between patterns in the language. The fact that some patterns build on more than one other pattern (i.e., have arrows from more than one other pattern to themselves) indicates that the structure of the language cannot be represented as a simple hierarchy. One pattern that builds on more than one other pattern is Promote and Add (PA). PA implements heterogenous addition where the operands are of the same hierarchy. It builds on both Promotion Ladder (PL) and Homogenous Addition (HA), using PL repetitively to promote the object of more specific type to the more general type and HA to then perform the addition. The language structure diagram shows arrows to PA from both PL and HA.
Cross Linkage
Example (software system):
If the system structure is complex Then overlap and use cross linkages to capture complexity.
Decoupling an abstraction from its implementation so that the two can vary independently is a common programming problem. Consider, for example, developing a hierarchy for real and complex numbers.
Real is a specialization of Complex, so class Real inherits from class Complex. But having Real as a subtype of Complex means that each Real number has an unnecessary imaginary part, because the inheritance transformation comprises both interface and implementation. One way of solving this problem is to separate the interface and implementation inheritance so that a number's implementation is not tied to its interface. The existing inheritance hierarchy is split hierarchy into two hierarchies, one of which represents interface inheritance and the other implementation inheritance. The hierarchies are connected by each object from the interface hierarchy maintaining a pointer to an object from the implementation hierarchy, whose particular type can be determined at run-time. The above situation highlights a case where a simple hierarchy does not provide the complexity of structure needed to solve a problem. The solution creates a cross link: the one hierarchy is split into two, and the pointer acts as a cross link between them. The above problem and solution are outlined in the Bridge pattern (Gamma, Helm, Johnson and Vlissides, 1995).
Example (architectural pattern language): Alexander describes the connections between patterns in his language as follows: Suppose we use a dot to stand for each pattern, and use an arrow to stand for each connection between to patterns. Then [A• Æ• B] means that the pattern A needs the pattern B as part of it, in order for A to be complete; and that the pattern B needs to be part of the pattern A, in order for B to be complete. If we make a picture of all the patterns which are connected to the pattern A, we see then that A sits at the center of a whole network of patterns, some above it, some below it. [diagram omitted] Each pattern sits at the center of a similar network. And it is the network of these connections between patterns which creates the language. (Alexander `1979, p. 313) Clearly, it is not possible to represent Alexander's network of patterns as a simple hierarchy. Each smaller or more fine-grained pattern can be connected to several more coarse-grained patterns: a pattern is not restricted to being part of just one larger pattern, as it would be in a simple hierarchy. For example, Entrance Transition can be both an elaboration of Family of Entrances and an elaboration of Main Gateway.
Example (architectural system): In A City is Not a Tree (1965), Alexander argues that the structures of a city are too complex to be captured in a simple hierarchy: a tree-like structure. Further, he argues that cities whose design is based on such a tree structure are unsuccessful, destructive and fail in their ultimate aim to improve the human condition. In contrast, successful
cities have a more complex structure of interactions or cross-linkages that can be represented by a semi-lattice. In Scattered Work (1977), Alexander argues that work zones need to be decentralized and woven in with residential zones, because a complete separation does not reflect the integrated nature of people's lives. People need interconnections between the many different aspects of their lives. Scattered Work is thus a pattern that generates cross linkages.
Example (biological system): In the “fight or flight” example described in Cluster Related Forces, the different systems in the body, such as the muscular, nervous and respiratory systems, all respond simultaneously to perceived danger. They could not do so were they each separate systems, structured as branches in a simple hierarchy: communication between different branches of the hierarchy would have to go all the way to the top of the hierarchy and down the other branch. It is only the interconnections between each system that allow a coordinated response: each system is connected both to the bloodstream and to other systems that are connected to the bloodstream. Different pathways of communication are used in different situations.
Local Repair If the system has an area that needs attention Then strengthen it by reinforcing the local symmetries in the area.
Context: A small part of a system needs to change.
Problem: How to repair a small part of a system whilst minimizing disruption to the overall structure.
Forces: Change does not happen in isolation – change to one part of system will affect other parts of system. The existing structure in the area concerned is no longer stable.
Solution: Identify and reinforce symmetry locally: identify and locally reinforce local symmetries in the area(s) where change is taking place.
Rationale: Systems in nature evolve through a process of symmetry breaking: structure-preserving transformations redistribute existing symmetry more locally. Reinforcing local symmetries in an area thus allows change whilst preserving overall system structure. If such change does not benefit the whole system then the area can be cleaned out.
Example (C++ Idioms Pattern Language): Doing local repair on a language might require any or all of adding/removing a pattern to/from the language, adding/removing to/from an existing pattern, or modifying the interconnections between patterns. Suppose the idioms language had been published without Detached Counted Body, which shows how to keep track of the number of handles to a body without modifying body code. Over time, some systems generated with the language would most likely need to manage multiple handles for one body without access to body code. Detached Counted Body might eventually emerge out of a range of implemented solutions as a proven, effective solution to such a problem. Local Repair suggests how to identify such solutions before they are widely recognized or even implemented: look for a transformation that reinforces local symmetries. As discussed in Local Symmetries, Detached Counted Body reinforces local symmetry: the existing handle remains as one, whole entity, but is transformed to be composed of two parts, each of which is like the original whole.
Example (software system): One aspect of implementing an application such as a document editor, in an object-oriented context, is choosing how to represent document elements, such as tables, figures, rows, columns, words and characters. More complex elements, such as tables and figures, need to be represented as objects. Simpler elements, such as characters, can be implemented as either objects or builtin types.
A solution that reinforces existing local symmetry more locally is using sharing to support large numbers of characters efficiently. One Flyweight (Gamma, Helm, Johnson and Vlissides, 1995) object can be created for each character in a character set and one instance of that object shared amongst all occurrences of the character in the document. Information that differs between character instances, such as font, size, and position on a page, can be calculated "from text layout algorithms and formatting commands in effect wherever the character appears". Flyweight preserves the conceptual symmetry of relationship between document element and program object. Every element of the physical document is still represented by a particular subclass and, conceptually, by a particular object of that subclass, even if the implementation of that object has changed. Document elements are still all drawn and formatted in the same way. In moving to shared character objects, Flyweight reinforces existing symmetry between all individual instances of the same character. Many attributes of a character that relate to drawing and formatting are fundamental: they do not change regardless of font, size, or position on a page, for example. Flyweight identifies this symmetry and reinforces it more locally by encapsulating in one object, whose size is, in fact, smaller than that of an individual instance, just those fundamental characteristics that are constant across object instances. Other, varying characteristics are determined from context when a document element is drawn. Flyweight thus does Local Repair.
Implementing characters as objects offers several advantages (Gamma, Helm, Johnson and Vlissides, 1995). It allows the "application's object structure … [to] mimic the document's physical structure" and therefore acts as a Clustering of Related Forces. It also allows characters and more complex elements to be "treated uniformly with respect to how they are drawn and formatted". This creates Local Symmetries: the symmetry of relationship between an element in the document and how it is drawn and formatted (at every level, every element in the document is represented by an object and drawn by the associated draw method) is preserved and reinforced at the character level. A further advantage is that extending the application by, for example, adding new character sets can be done without affecting other functionality: Piecemeal Growth can thus happen more easily.
Example (architectural pattern language):
The cost of representing objects as characters, however, can become prohibitive, as "even a moderate-sized document may require hundreds of thousands of character objects". Addressing this issue in a particular system means repairing the system, locally. One way of doing such repair is to represent characters as built-in types, rather than objects. Such a solution, though, comes itself at a high cost, because it negates the advantages listed above. It also does not preserve existing symmetry: the draw method for characters is no longer tied to the subclass representing the particular character being drawn, but to some other unrelated subclass in the system.
Example (architectural system):
In developing A Pattern Language, Alexander notes that some patterns emerged as a result of recognizing fundamental similarities in several other patterns. Common Areas at the Heart is one such pattern. It grew out of the recognition that several other patterns in very different contexts (residential housing in Peru, University of Oregon, clinics) all required a common area at the heart of a social group, positioned so that people would regularly walk through it on their way to and from other spaces. Adding Common Areas at the Heart to the language reinforces the symmetry of other patterns by explicitly recognizing it. It could be added to the language as a replacement of more fine-grained patterns, or such that those more finely grained patterns were an elaborated on Common Areas at the Heart.
In the architectural domain, there are distinct phases of construction and maintenance: growth and repair. In Alexander's view, though, what is growth in one context is local repair in another. Every act of building, then, ought also be an act of local repair in a broader context. For example, Site Repair (Alexander 1977) points out that a building should be built on the worst part of a site, not the best: rather than destroying a good part of a site by building something on it, the act of building itself can repair the worst area of the site. The construction of a building is thus an act of local repair to the broader
environment in which the construction takes place. Such construction, if done well, can be seen as reinforcing local symmetry in the sense that it replaces structure that doesn't fit with the environment with structure that does.
Example (biological system): Each cell has two complementary strands of DNA that interlock perfectly together. As a cell prepares to divide, the two strands split. Each strand then acts as a mold for a new complementary strand of DNA: a new strand that will interlock perfectly with the mold. While the cell is going through this division, a range of enzymes check the DNA strands for damage. Any damage is either repaired or the cell is destroyed. The process of cell division involves structure-preserving transformation on a cell, that creates local symmetries. Repairing DNA damage reinforces that symmetry by repairing or destroying any cell that will not divide into two exact copies of itself.
The Void If the overall system gets too tangled Then clean it out to create space for more development.
Context: The existing system structure has become convoluted and tangled.
Problem: How to further grow the system.
Forces: Adding more local symmetries will make the system more convoluted.
Solution: Excise the tangle by breaking some connections in the system, thus creating space for new growth.
Rationale: Natural processes work by periodically “cleaning out” when things get too tangled. For example, forest fires regenerate forests. A designed system should therefore be cleaned out when it becomes too tangled.
solution to be implemented, existing code related to the addition operation would need to be cleaned out to give space for the new solution to develop into.
Example (architectural pattern language): Alexander points out that a pattern language is continually evolving. As part of that process, some patterns are removed from the language: A group of us began to construct such a language eight or nine years ago. To do it, we discovered and wrote down many hundreds of patterns. Then we discarded most of these patterns during the years … (Alexander 1979, p.331)
Example (architectural system): Stewart Brand points out that neglect is a critical factor in a building being able to age well. He points out that most buildings are forced to continually adapt unhealthily to the latest, illusory fashions and fads, and according to market-driven forces. But those buildings that for whatever reason – poverty, location – are neglected and survive "that crucial second thirty years when a building is out of fashion, out of repair, and most vulnerable to demolition" (Brand 1997, p.100) gain space to adapt slowly and functionally: to adapt piecemeal, and thus age well. Entrance Transition (Alexander 1977) highlights the transitional role played by entrances to buildings. It points out that an entrance is a transition between inside and outside, and private and public space. The pattern provides evidence suggesting that people using entrances need space for the actual transition itself: the change from inside to outside, private to public, carries with it appropriate behavioral change that is gradual and needs space and time in which to take place. An Entrance Transition thus functions as a Void between two different spaces. It breaks some of the connections between the two spaces – perhaps by restricting vision from one to the other, and/or being an archway between them – allowing each space the space to retain its own distinct identity.
A pattern language is an evolving artifact in a constant state of flux. At times, patterns will be removed from the language to create space for other patterns to be added.
Positive Outdoor Space (Alexander 1977) describes the kind of shapes that buildings should create around them, by their shape. It argues that buildings that create convex spaces around them create a positive space, or “void”. Buildings that do not create convex spaces around them do not create any distinctly identifiable spaces around them. When a building creates positive outdoor space, that space works as a void, or space between buildings that people identify as distinct and feel comfortable in.
Example (software system):
Example (biological system):
In an algebraic hierarchy implemented in C++, an operator like addition might be implemented by providing each class with an addition method for all possible type combinations. But if the number of types catered for increased, then such a solution could quickly become unworkable, due to the combinatorial explosion in type combinations. A solution such as Homogenous Addition would be more appropriate, but in order for such a
As part of the process of development, stem cells specialize for particular tasks. The first specialization is into organ, skin and gut, or nerve cells. Taking cells for organ development as an example, in order for those cells to continue to divide and replicate and form a distinct entity which is an organ, they need to be more separate from the mass of cells that they are originally part of. They cannot develop a distinct identity while remaining
Example (C++ Idioms Pattern Language):
fully connected to all the other cells around them. Thus, a sac of fluid (fluid not being made up of cells but simply being a chemical solution) forms around the organ cells, creating a “void” in which the organ can develop.
5
Conclusion
Existing and often longstanding research on the ways that systems form and evolve has much to offer those developing pattern languages. The importance of symmetry breaking for understanding system adaptation is reinforced by informal analysis of symmetry in several domains. If, as was the main supposition of this paper, pattern languages can be treated as designed systems, then the pattern language produced here could be used to analyze itself and the processes by which it came about.
6
References
ALEXANDER, C.A. (1964): Notes on the Synthesis of Form. Cambridge, MA, Harvard University Press. ALEXANDER, C.A. (1965): A City is Not a Tree. In Design After Modernism: Beyond the Object: 67-84. THACKARA, J (ed). London, Thames and Hudson. Originally published in Architectural Forum 122(1):58-62 (Part I) and 122(2):58-62 (Part II). ALEXANDER, C.A. (1977): A Pattern Language. New York, Oxford University Press. ALEXANDER, C.A. (1979): The Timeless Way of Building. New York, Oxford University Press. ALEXANDER, C.A. (1996): The Nature of Order (Book 1): The Phenomenon of Life. New York, Oxford University Press. Unpublished draft. ALEXANDER, C.A. (1996a): The Nature of Order (Book 2): The Process of Creating Life. New York, Oxford University Press. Unpublished draft. BRAND, S. (1997): How Buildings Learn. London, Phoenix Illustrated. CAMPBELL, N.A. (1996): Biology (4th edn). Menlo Park, CA, Benjamin/Cummings. COPLIEN, J.O. (1992): Advanced C++ Programming Styles and Idioms. Reading, Massachusetts, AddisonWesley. COPLIEN, J.O. (1998): Space: The Final Frontier. C++ Report, 10(3):11-17. COPLIEN, J.O. (1998a): Worth a Thousand Words. C++ Report, 10(5):51-54. COPLIEN, J. (2000): C++ Idioms Patterns. In Pattern Language of Program Design 4. 167-200. HARRISON, N., FOOTE, B. and ROHNERT, H. (eds). Lucent Technologies/ Addison-Wesley. COPLIEN, J.O. (2000a): Software Patterns. New York, SIGS Books & Multimedia. COPLIEN, J.O. (2000b): The Future of Language: Symmetry or Broken Symmetry?. Proc. VS Live 2001, San Francisco, CA.
COPLIEN, J.O. and ZIAO, L. (2001): Symmetry Breaking in Software Patterns. Springer Lecture Notes in Computer Science Series, LNCS 2177:37-54. FOOTE, B. and YODER, J. (2000): Big Ball of Mud. In Pattern Language of Program Design 4. 167-200. HARRISON, N., FOOTE, B. and ROHNERT, H. (eds). Brian Foote and Joseph Yoder/ Addison-Wesley. FOWLER, M. (1999): Refactoring: Improving the Design of Existing Code. Reading, Massachusetts, AddisonWesley. GAMMA, E., HELM, R., JOHNSON, R. and VLISSIDES, J. (1995): Design Patterns: Elements of Reusable Object-Oriented Software. Reading, Massachusetts, Addison-Wesley. HANMER, R. (1999): Traffic Congestion Patterns. Proc. Pattern Languages of Programs 1999, Chicago, IL, available as at October 1992 from http://jerry.cs.uiuc.edu/~plop/plop99/proceedings. MESZAROS, G. (1996): Half-object + Protocol. In Pattern Languages of Program Design 2. 129-132. COPLIEN, J.O. and SCHMIDT, D. (eds). Bell Northern Research/ Addison-Wesley. MONTGOMERY, W.A. (1998): Personal correspondence with Coplien, J.O. as quoted in COPLIEN, J.O. Worth a Thousand Words. C + + Report, 10(5):51-54. ROSEN, J. (1995): Symmetry in Science: an Introduction to the General Theory. New York, Springer Verlag. STEWART, S. and GOLUBITSKY, M. (1992): Fearful Symmetry: Is God A Geometer?. Oxford, Blackwell Publishers. WINOGRAD, T. and FLORES, F. (1986): Understanding Computers and Cognition. Norwood, New Jersey, Ablex Publishing Corporation.