Published in Springer Lecture Notes in Computer Science, LNCS 2177, October 2001, ff. 37.
Copyright © 2001, Lucent Technologies and UMIST. All Rights Reserved.

Symmetry Breaking in Software Patterns



James O. Coplien
Bell Laboratories, ILIE00 2Z307, 263 Shuman Blvd, Naperville, IL 60566 USA, +1-630-713-5384,
Department of Computation, UMIST, P. O. Box 88, Sackville Street, Manchester M60 1QD, UK, +1-515-779-7421,
cope@research.bell-labs.com

Liping Zhao
Department of Computation, UMIST, P. O. Box 88, Sackville Street, Manchester M60 1QD, UK, +44-161-200-3340, liping@co.umist.ack.uk




Abstract. Patterns have a longstanding identity in the scientific community as results of a phenomenon called symmetry breaking. This article proposes a formalism for software patterns through connections from software patterns to symmetry and symmetry breaking. Specifically, we show (1) the ties from Alexander's work to symmetry and symmetry-breaking foundations; (2) many programming languages provide constructs that support symmetry; (3) software patterns are the results of symmetry breaking, compensating for design shortfalls in programming languages. The proposed pattern formalism may be useful as a foundation for pattern taxonomies, and to differentiate patterns as a design discipline from heuristics, rules, and arbitrary micro-architectures.

1 Introduction

Most contemporary attempts to formalize patterns (e.g., [14], [15]) ignore both the prior art and the most relevant foundations for potential formalization. This paper shows that symmetry lies at the very foundation of the pattern formalism. The paper also shows that the symmetry formalism has historically been broad enough not only for the natural sciences and Alexander's work, but that it can serve software as well.

Pattern and symmetry are closely related. The formation of pattern can be characterized by symmetry operations, which, in the sense of classic symmetry, are rigid motions of geometric object [33]. We believe that the geometric nature of classic patterns has been the main inspiration of Alexander’s work ([1], [2], [3]). An early realization of our research is that most of these structural properties relate to symmetry. Leading software pattern practitioners have also recognized that the best software patterns are also geometric in appearance and organization for reasons of composability, which is in concert with Alexander's theories of patterns and centers.

The next section introduces symmetry concepts and group theory, which is the prerequisite for the paper. Section 3 gives an overview to Alexander’s theory and its connection to symmetry. Section 4 presents symmetry in O-O software. Sections 5 and 6 introduce symmetry breaking as a foundation for patterns. Section 7 illustrates symmetry and symmetry breaking in programs and designs. Section 8 proposes a formalism for software patterns. We conclude the paper in Section 9.

2 Group Theory and Symmetry Concepts

Group theory offers constructs to formally characterize symmetry through symmetry groups. This section gives a brief introduction to group theory and symmetry ([28], pp 9-10):

A group is a nonempty set G together with a law of composition (a, b) _ ab : G x G -> G satisfying the following four axioms:

  1. Closure. For all a, b element of G, the set G is closed under composition:           ab, ba element of G.
  2. Associativity. For all a, b, c element of G, the composition is associative:        (ab)c = a(bc).
  3. Existence of An Identity Element. For all a element
of G, there exists an element element of G such that ae = a = ea .
  4. Existence of Inverses. For each a element of G, there exists an a-1 element of G such that aa-1 = e = a-1a.

A symmetry of an object is a transformation that leaves the object apparently unchanged ([30], p.28). Classic symmetry transformations are rigid motions, such as reflection, rotation, translation, and their combinations. For example, the appearance of the human body is invariant under reflection such that the distances from any origin point to its mirror image is preserved with respect to the reflection center.

Symmetry is more fundamentally about invariant change, i.e., change, yet the same. In geometric sense, it means that objects don't stretch or deform as they are translated or rotated. This basic idea extends the possibilities of symmetry beyond geometric objects. For example, symmetry principles in physics, such as gauge symmetries, obey symmetry properties but are not strictly geometric.

Rosen ([28], p2) defines: "Symmetry is immunity to a possible change" in the context of the broad field of natural sciences. Immunity to the change means that some transformation brings the object into coincidence with itself. Symmetry means invariant change or transformation invariant. Rosen defines a symmetry transformation as a bijective (one-to-one and onto) mapping of a state to an image state equivalent to the object state ([28], p.80). State equivalence is defined by an equivalence relation for a state space of a system, such that any two states satisfy the conditions of reflexivity, symmetry, and transitivity. A symmetry transformation S can be denoted as:

     u -S-> v = u     or     S(u) = v = u

for all states u ([25], p.80).

In the above definition, v = udenotes the equivalence relation between the states v and u. A subspace comprises a subset of states of a state space. An equivalence subspace is a subspace within which all the states are equivalent to each other. This leads to a general definition of symmetry group:

The set of all invertible symmetry transformations of a state space of a system for an equivalence relation forms a group, a subgroup of the transformation group, called the symmetry group of the system for the equivalence relation ([28], p. 80).

A symmetry group doesn't comprise objects (buildings, software objects) of a system, but rather a set of symmetry transformations on these objects. The symmetries we investigate in this paper are those that are expressed by programming language constructs. The symmetry groups will be the compositions of symmetry transformations embodied in programming language features with respect to a certain set of invariants.

3 Alexander's Theories

Work on software patterns was largely inspired by Christopher Alexander's pattern research and application in the fields of architecture and urban design. We summarize Alexander’s work here.

3.1 A Geometric Basis

As an architect, Alexander deals with geometry. Alexander views geometry to be the essence of what he was doing and this view is in line with Klein’s:

… in Klein’s words, ‘geometrical properties are characterised by their invariance under a group of transformations.’ Each type of geometry has its own group … Group theory provides the common ground that links different geometries ([30], p. 44).

3.2 Pattern

Alexander's publications on architecture in the late 1970s focused on design elements called patterns [3]. Those patterns formed a pattern language, which can be partitioned into numerous smaller pattern languages [1]. The goal of pattern languages was to contribute to "the quality without a name," a deep feeling of architectural excellence suitable to a given culture

A pattern is a description of an architectural relationship between design parts. It is also an architectural transformation that integrates parts into a larger whole. Alexander’s patterns are geometric in nature. A pattern language allows a builder to build a house by applying one pattern at a time, in sequence.

3.3 Theory of Geometric Centers

While the people using pattern languages had produced good community houses, Alexander soon realized that pattern languages alone were inadequate to achieve the beauty he sought. There were two problems: the economic processes of building didn't support piecemeal growth, and the people using the pattern language had the skills necessary only for gross scales of beauty, not the very fine artisanship necessary for wholeness at all scales. These concerns prompted him to develop a new theory consistent with, but fundamentally different than, the theory of patterns. This theory is based on geometric centers and a piecemeal growth process. Informally, a center is something that draws the eye, a geometric region that we notice. Centers combine to form geometrically attractive configurations. Patterns usually are stereotypical centers that carry an aesthetic--likely culturally attuned--in addition to any visceral beauty they may have. Centers drive more at the visceral beauty of pure geometry.

The process for building with centers is a simple process of structure-preserving transformations. One finds the weakest center in a whole and strengthens it by adding new centers that make it more whole. If the overall result is more whole, then the process iterates to the next center. Each of these transformations increases wholeness while preserving the structure of the whole, though there are adjustments in the details. A given transformation can clean out a center that has become too messy, but the overall structure is preserved.

In mathematical terms, a structure-preserving transformation is called a homomorphism ([28], p.23). Briefly, a homomorphism is a many-to-one mapping from one group to another. If a homomorphism is bijective, i.e., one-to-one and onto, it is called an isomorphism. So an isomorphism is a bijective homomorphism. Although homomorphism preserves structure, homomorphic groups do not have the same structure unless they are isomorphic.

Each transformation strives to strengthen a center by reinforcing one or non-orthogonal structural properties in the whole, including 15 structural properties like Levels of Scale, Alternating Repetition, Local Symmetries, and Deep Interlock and Ambiguity [2]. We note that most of the structural properties are directly linked to symmetry. For example, Deep Interlock and Ambiguity and Alternating Repetition exhibit bilateral symmetry, and Echoes exhibit translational symmetry. Many of these structural properties show through in Alexander's patterns as City-Country Fingers [1] which is an example of Deep Interlock and Ambiguity. Alexander emphasizes this:

There is a profound connection between the idea of a center, and the idea of symmetry.

  1. Most centers are symmetrical. This means that they have at least one bilateral symmetry.
  2. Even when centers are asymmetrical, they are always composed of smaller elements or centers which are symmetrical ([4], p. 42-43).

4 Symmetry in Object-Oriented Software

In this section, we explore some examples of symmetry groups in object-oriented programming languages.

4.1 A Geometry Basis for Software

Gabriel posited in 1996 that geometry, for us in computer science, translates to the structure of the code ([7], p. 34). That is one geometry of a program, but there are others, including its modular [8] and temporal [9] structure. Coplien's more recent work [13] attempted to establish a geometric basis for C++ idioms for types whose operations have inverses. That effort was an attempt to bring some of the popular Design Patterns [16], which draw in part on those idioms, better in line with Alexander's geometric theories.

Here we attempt to explore symmetry in software from the perspectives of group theory. And interestingly, if one goes back before patterns to the very basics of polymorphism, one finds applicability of group theoretic foundations for object orientation to be strikingly strong despite the fact that no popular link ever joined the two fields. Consider this quote from a plant physiologist in a math journal circa 1986:

…new theories of symmetry treat as equal also such objects (such equalities) which were considered as essentially different in previous theories (respectively, as inequalities). The unique reason why these equalities have been adopted is always the same thing, i.e. the existence of real or/and mental operations making the objects O, compared in features F, indistinguishable. ([32], p. 396)

This is almost a textbook definition of (object-oriented) polymorphism.

4.2 Classification as Symmetry

A class in an object-oriented program defines a symmetry. The common knowledge of the class concept is related to abstract data type and encapsulation. However, we can also say that a class classifies objects. A class establishes an invariance relationship between the class and its objects and makes all its objects analogues with respect to the class structure. Class data and functions remain valid to all the objects. A class in this sense defines an analogy, which is a symmetry ([28], p. 164).

We can validate the symmetry of a class using Rosen’s definition. Recall from Section 2 that symmetry is immunity to a possible change. We can analyze the two aspects of change and invariance as follows:

  1. Change. A class can be applied to more than one object; the objects to which it is applied can be switched from one to another.
  2. Invariance. The class structure is immune to the switching-abouts of objects, i.e., what it is true remains true.

Recall also from Section 2 that changes are represented by transformations. The above shows that the order of the objects in a class is immaterial. Mathematically, we can represent the changing orders, switching-abouts as a set of transformations. We can show that these transformations form a group. For example, changing object o1 to o2 to o3 is equivalent to changing from o1 to o3. This is the closure property of the group. Changing is associative, in either direction (inverses); no changing is the identity transformation. A formal proof of these four properties will appear in a separate paper.

A linguistic realization of such transformations is the copy constructor, which satisfies the four properties of the group. More importantly, such transformations are implicit, and the fact that a user can create more than one object without worrying about the sequence of the creation owes to the symmetry of the class.

It should be noted that many language features--inheritance, subtyping, overloading, and others--are ways of expressing classification. By the above analysis, all such features are related to symmetries.

4.3 Inheritance as Symmetry

Cook and Palsberg [5] define inheritance as an operation on generators that transform a base class into a (distinct) derived class. In this section, we only consider one use of the inheritance operation, i.e., the use of inheritance for type derivation or subtyping. Only then can we say that inheritance preserves the structure of the base class. Other uses of inheritance, such as for implementation convenience or function overriding, do not preserve the class structure and therefore will not be considered here.

When inheritance is used for subtyping, it creates a type hierarchy [22]. A type hierarchy consists of subtypes and supertypes, where objects of a subtype provide all the behavior of objects of its supertype plus something extra [22]. A type hierarchy satisfies the Liskov Substitution Principle (LSP):

If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, them S is a subtype of T. [22]

That is, there are invariants (in this case, behavioral invariants) that hold for a program under a transformation that substitutes objects of type S for those of type T. Behavior is symmetric with respect to subtyping--only here, the constancy of behavior is itself the litmus test by which subtyping is judged, not vice versa.

Given a subtyping path in a type hierarchy, we say that classes belonging to this path are equivalent in that they have the same invariants as the base class. We define all the classes in such a single path as a set or a state space as per Rosen’s definition in Section 2. We define an equivalence relation for this set as the base invariant equivalence, denoted as = such that it holds for any pair of the classes, e.g., x, y, z, in the set:

  1. Reflexivity. x = x for all x (Every class of the set is equivalent to itself).
  2. Symmetry. x = y <=> y  = x for all x, y (Any pair of classes is equivalent).
  3. Transitivity. x = y, y = z = x = z for all x, y, z.

In Section 2 we give the definition that a symmetry transformation is a bijective (one-to-one and onto) mapping of a state to an image state equivalent to the object state in a state space for an equivalence relation. Here the state space is a set of classes of a given subtyping path. States in this state space correspond to classes. We represent an inheritance operation or derivation as D such that:

     s -D-> y = x     or     D(s) = y = x

for all classes x in the set.

We now prove an inheritance operation is a symmetry transformation. Consequently, we need to prove (1) an inheritance operation is invertible and (2) the set of inheritance operations for a set of classes as defined above form a symmetry group.

To prove the invertibility of the inheritance operation, we need to show:

     y -D-1-> x = y     or     D-1(y) = x = y

for all classes y in the set.

What is the inverse of the inheritance operation? Programming languages are graced with pragmatics that are not pure theory, and there is rarely a corresponding language realization of the operation that derives from a subtype to a supertype, i.e., a supertype cannot inherit from a subtype. However, for example, the (now vestigial) class slicing feature of C++ is a way to restore the original state of the system when an instance of some class is supplied in a context where a less derived class is expected. From this point of view, a slicing operation corresponds to or plays a role of inverse. In other programming languages, inverses might be implemented through conversion operators or constructors (e.g. in Smalltalk, many algebraic types respond to messages such as asInteger).

Since our goal is to establish a formalism for patterns, we can still define an inverse of an inheritance operation as a mathematical operation whose linguistic support is missing for practical reasons. Hence we have the inheritance operation whose inverse remains to be mathematical.

We shall now prove that the set of all invertible inheritance operations on the classes in a given subtyping path forms a symmetry group.

  1. Inverses exist in the sense of the above assumption.
  2. Closure follows from transitivity of the equivalence relation. For the inheritance operation D on all classes x, y, and z, the composition of DD is the result of consecutive application of D, such that:
  3. x = y = D(x),

    y = z = D(y) = D(D(x)) = (DD)(x),

    x = z = (DD)(x),

    x = z = D2(x)

    Thus for the inheritance operation D their compositions D2, D3, … are also inheritance operations.

  4. Associativety holds for composition by consecutive application. It is evident that using the closure property, we can obtain:
  5. D(DD) = (DD)D = D3

    Hence we have proved the associativity.

  6. The identity transformation is a null inheritance operation. In other word, it is a do-nothing operation, such that:

     x -I-> x = x     ;or     I(x) = x = x

All the invertible inheritance operations on the classes through a single subtyping path form a symmetry group for class invariants. We may consider inheritance operations as translations that transform classes in time [33]. We can represent such translational symmetries as a linear train of iterations:

… D-3 = D-1D-1D-1, D-2 = D-1D-1, D-1, D0 = I, D1 = D, D2 = DD, D3 = DDD, …

Translation and other temporal symmetries (transformation over time) are common themes in computer programs, as we shall also see in Section 4.4. In fact, temporal symmetry is a fundamental phenomenon in symmetry breaking in the natural sciences. For example, the idea that time is reversible is called the T symmetry in the classic CPT symmetry model of physics; symmetry breaking in all of these symmetries is the very reason that anything exists ([19], pp. 79-81).

Generalizing the ideas of classification and temporal symmetry, we can define symmetry in terms of any invariant or notion of equality ([32], pp. 395-396) for a system under consideration.

4.4 Overloaded Operators as Symmetries

Operator overloading, and associated friendship relationships in C++, have consciously been provided to express symmetry ([21], p749). Overloaded arithmetic operators support reflection symmetry, freeing the user from distinguishing between the left and the right operands, as A+B = B+A and A*B = B*A.

Overloaded operators not only can support reflection, but also translation as well. For example, overloaded "+", "-", "*", "/" free the user from distinguishing between primitive numbers and objects.

5 Symmetry Breaking and Pattern

When a system encounters stress it loses symmetry. The phenomenon of symmetry breaking may be explained in terms of symmetry groups. Consider the common example of a proto-planet rotating in space, a sphere of symmetry group O(3). If it spins too fast it may become pear-shaped, losing one degree of symmetry so as to fall into O(2). If the spinning continues it may break into a planet/moon system which still has overall symmetry O(2), though it has lost the spherical symmetry of the original system. This is called spontaneous symmetry breaking in physics [24], or symmetry-breaking as we call it here. Symmetry doesn't really "break", but is just reduced or redistributed in the effect produced by symmetry in the cause. When a symmetry group is broken, it results in a new group that is a subgroup of the original. Note in this moon-formation example, each of the parts still has O(3) symmetry, even though the system has been reduced to O(2).

Symmetry breaking results in patterns, or more precisely, reveals patterns, for too much symmetry isn’t perceived as pattern [30]. For example, a regular n-sided polygon belongs to the dihedral group Dn. When n is infinitely large, the polygon is close to a circle, which isn't rich in structure. But if some of the symmetries in this polygon break, or when n becomes smaller, say, 6, 5, 4, or 3, we begin to see the shape of the polygon. The phenomenon of symmetry-breaking was first discovered in 1923 by Ingram Taylor when studied the dynamics of the fluid flow, which was known as hydrodynamic "symmetry paradox":

This paradox, that symmetry can get lost between cause and effect, is called symmetry-breaking. In recent years scientists and mathematicians have begun to realize 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. ([30], p. xviii)

The idea of symmetry breaking carries through to Alexander's patterns. Varied Ceiling Heights [1] is a symmetry-breaking pattern. Light on Two Sides of Every Room [1] is another example: a perfectly symmetric room would have either no windows or would have windows on four sides. A room with windows on four sides would be perfectly symmetric and would lack the quality Alexander seeks in his work. He remarked that too much symmetry is a bad thing:

Living things, though often symmetrical, rarely have perfect symmetry. Indeed perfect symmetry is often a mark of death in things, rather than life.

I believe the lack of clarity in the subject has arisen because of a failure to distinguish overall symmetry from local symmetries. ([2], The Phenomenon of Life, 44.)

and:

In general, a large symmetry of the simplified neoclassicist type rarely contributes to the life of a thing, because in any complex whole in the world, there are nearly always complex, asymmetrical forces at work--matters of location, and context, and function--which require that symmetry be broken. ([2], The Phenomenon of Life, 45.)

Symmetry breaking also plays an important role in the characterization of Alexander’s 15 structural properties. Local Symmetry requires some symmetry be broken. Roughness, Gradients, Echoes, and Levels of Scale all exhibit symmetry, but lack perfect symmetry characteristic of the next largest symmetry groups (perfect smoothness, bilateral symmetry, and equal size).

The idea of symmetry breaking also extends to software patterns, as we shall see in Sections 6 and 7. For example, class extension is a symmetry; Bridge is a pattern that reflects symmetry breaking under the stress of certain design desiderata.

6 Patterns and Symmetry Breaking in Software

As discussed in Section 4, many programming language constructs express symmetry. When those constructs fail to solve design problems, programmers often resort to patterns to express the design in the programming language. This section attempts to show that most software patterns are a result of symmetry breaking.

6.1 Breaking Type Symmetry

Assume we have a class, List<T> in some library. We wish to derive from it a new type, Set<T>. Let’s see if such derivation can preserve class invariants in List<T>, as discussed in Section 4.3.

First, a set is not a subtype of a list, nor is the reverse true. For example, by the principle of extensionability, sets with the same members are equal [17]. So adding the same member twice to a set is the same as adding the member only once. However, adding the same member twice to a list is different from a single insertion.

Therefore, deriving a set from a list breaks the symmetry that subtyping attempts to conserve. We start with a List and want to transform it into a Set. The symmetry breaks. Where does it go?

Imagine if the symmetry did not break, i.e., in the normal subtyping situation, the relationship between a subtype and its supertype would be denoted as in Figure 1. However, since the symmetry is broken, the new relationship lacks the symmetry of Figure 1, reflecting only local symmetry (Figure 2). This is known as the Adapter pattern. In this pattern, the insert and has methods appear in all three classes.

Most of the structural patterns (Adapter, Bridge, Composite, Decorator, and Proxy) [16] deal with the tension between language constructs that express symmetries, and the small perturbations that make those constructs unsuitable for use. Some of the behavioral patterns (Iterator, Memento, Observer, State, Strategy, Template Method, and Visitor) can also be easily described in terms of temporal symmetry breaking. Other design patterns take more imagination to describe in symmetry-breaking terms, which raises the question of whether they are patterns in the Alexandrian vein.

From the perspective of symmetry breaking, a pattern is a way of redistributing the forces in a symmetric system in light of some instability. Symmetry is reduced, but not lost; it is redistributed in the pattern. The exact way in which it is redistributed is difficult to predict. Global symmetries are lost, but local symmetries are preserved.

We want to point out here that the term local symmetry is not an original Alexandrian formulation, but is a standard term in the symmetry group communities of crystallography ([23], p. 29; [29], p. 567) and quantum physics ([24], p. 173).

6.2 Breaking Function Symmetry

Multiple dispatch is a form of symmetry breaking. In a Liskov type hierarchy, subtype methods have a level of equivalent semantics defined by the bounds of pre- and postconditions, semantics that programmers usually associate (however informally) with the method selector. In a classful language these symmetries in a type hierarchy preserve class invariants, as discussed in Section 4.3.

When a type hierarchy is used for dynamic binding, a member function is chosen according to the type of its instance at run time. The symmetry breaks if the member function depends on the types of more than one object; the LSP no longer holds. . This is a form of symmetry breaking for which the longstanding linguistic solution is multiple dispatch. This of course is the Visitor pattern [16].

The "Promote and Add" pattern is also symmetry breaking. The "+" operator is interesting not only because it supports symmetries as discussed in Section 4.4, but also because it has a highly symmetric signature:

T x T -> T

If we picture "+" operating between pairs of objects, where each object participates in a class hierarchy, we get a nicely symmetric picture as in Figure 3.

Figure 3

But reality is messier because of the need for heterogeneous addition. For example, it makes sense to ask for 1 + 4.5, as in Figure 4--a broken symmetry (and it's independent of multiple dispatch or polymorphism).

The solution is a geometric transformation, a pattern, called Promote and Add, originally written up as a C++ idiom [13], but which can also appear in broad architectural contexts as patterns such as Add a Switch [9]. It adds local symmetries by promoting heir types to their parent types as a prelude to addition, thereby reducing the problem to that of the first picture. It is a structure-preserving transformation that adds centers (the transformations from derived types to base types) to the first picture. The resulting Smalltalk bears out the pattern explicitly in methods such as sumFromInteger, asDouble, and ArithmeticValue>>retry.

Figure 4

6.3 Breaking Class Symmetry

We usually think of types as abstract specifications with classes as their language realizations. The class structure often follows the type structure. But sometimes, even though the type structure reflects a structure-preserving transformation consistent with the LSP, the class structure does not preserve structure for reasons that owe to language implementation peculiarities. This means that the symmetry of the class structure is broken, and a pattern usually results.

Again consider class Complex, whose implementation is two real numbers. Abstractly we can talk of the symmetry group of type Complex as comprising transformations that preserve class invariants as discussed in Section 4.2. These invariants hold, with respect to member function behavior (type symmetry) for heir classes such as Real and Integer, as one would expect.

Even though the member functions are preserved in the transformations from Complex to derived types, the structure of the Complex class may not be preserved in Real and Integer. In particular, Complex has two reals and Real would have only one. Eiffel would call this restriction inheritance ([27], p. 826). In the representation of the class, there is at best a weakened symmetry between Complex and Real (one could argue that they are symmetric with respect to the preservation of the real component) but all structure is lost by the time we get to Integer. Symmetry slowly breaks as we descend the hierarchy. We find the same case for Ellipse and Circle, as in Meyer ([27], p. 467).

In either of the cases, we lose symmetry when the inheritance transformation is not structure preserving as required in the LSP, so we have symmetry breaking. What results is usually a pattern; in this case, something like Bridge might be in order.

7 Other Examples

We can look beyond object-oriented programming language constructs to find many examples of symmetries and symmetry breaking in software design.

Symmetries abound in programs and can be found beneath almost all programming structures. In addition to symmetries we have discussed in Section 4, loops are spiral time symmetries. Simple conditionals can be viewed as symmetry breaking, while case statements can also be viewed as symmetries that hold the entry and exit points invariant. Argument defaulting is a form of overloading where the symmetry is the preservation of some argument types. Rather than focusing on these programming-in-the-small symmetries, in this paper we focus on the design structures that are of greater interest to the field of object orientation.

Patterns are introduced as a result of symmetry breaking in all of these cases. We showed above, in Section 6.2.2, what happened when the symmetry of overloaded operator + broke. This is hardly an object-oriented phenomenon, either. The work in [10] introduced the notion that functional and applicative languages may succumb to these analyses more readily than object-oriented languages do, owing to the largely geometric nature of the source and translated program structures.

The symmetries supported by language constructs might be used as a basis for objectively comparing the relative expressive power of a programming language. For example, the number of symmetries and the type of symmetry might be used as such an objective indicator. We suggest further empirical work in this area.

We find patterns outside the programming language context, too. Patterns such as Half Object plus Protocol (HOPP) [25] are an obvious example of symmetry-breaking reminiscent of bifurcation symmetry. It should be noted that there is nothing fundamental about the system in which HOPP is embedded that suggests that symmetry break in a way that results in two objects; it could just as well break into three objects, as it does in the pattern Three-Part Call Processing [9].

In the Cascade pattern for a public transport system [34], it was observed that both the driver duty object and its builder were cascades. A driver duty can be seen as a result of a translation of its builder (the Prototype pattern) or as a rotated bilateral symmetry. Other examples in telecommunication software are documented in [9].

Model-View-Controller expresses symmetry between a Model object and a User object. What breaks the symmetry is the need for the User object to maintain multiple views of the Model. That gives rise to the View object itself, and to the Controller as a dispatcher from the User to the Model and View. [Trygve Reenskaug, Personal conversation, June 1999].

Fresh Work before Stale [26] is a classic example of temporal symmetry breaking. The pattern creates a broken symmetry in the flow of work that gives priority to new work over pending work, and throughput increases as a result.

Factory Method and Abstract Factory [16] break the symmetry of the structures of the object produced by instantiation processes. Template Method breaks the symmetry of individual algorithms.

Domain analysis techniques are rooted in axioms of commonality and variation [11]. Group theory may provide constructs for formalizing this structure as well: symmetry is about commonality invariance; symmetry breaking is about variations.

8 Towards A Pattern Formalism

So, what is a pattern? The question is the closest thing to a religious debate in computer science since the debate raged about "What is object orientation?" There are many qualities often used to distinguish, or sometimes distance, patterns from mainstream academic computer science. Among these are beauty, maturity of ideas, and attunement to human comfort. Here we try to put these elements in perspective.

Does Alexander's stipulation that a pattern only exists within a pattern language ([3], p. 312) relate to symmetry and symmetry breaking? Remember that a pattern is a transformation, a transformation that breaks some symmetry present in the original system, adding asymmetry. The original system defines context; without that context, there may in fact be no symmetry to be broken. What might otherwise pass as a pattern, out of context, may simply be a symmetry. We can also explain the relationship between symmetry and symmetry breaking as a causal relationship: the original system exhibiting the original symmetry is the cause; the transformed system in which some symmetry is broken is an effect.

As mentioned early, broken symmetry doesn’t necessarily mean asymmetry unless all the symmetry is lost. Although it is not the topic of this article, we wish to point out that symmetry only exists with respect to asymmetry ([28], p. 161) and asymmetry is a frame of reference to symmetry.

One may criticize the design patterns [16] as not meeting the Alexandrian criterion of necessarily emanating from a whole, from a pattern language. However, some of the design patterns constitute patterns that form a pattern language for a particular design problem. Symmetries that these patterns attempt to preserve or break may be identified. This leaves hope that the design patterns may be legitimized as patterns in a fashion tantamount to, or at least analogous to, the closely related idioms work [13].

One key suggestion for future work is to show that a pattern language forms a contextual framework for the formalization of symmetry breaking (the very definition of individual patterns), and that such a framework forms not only a language, but also an algebra of specification. The outcome seems likely; after all, a geometry is essentially an algebra of symmetries.

Based on the above analysis, we posit the following formal definition of a pattern:

Definition: A pattern characterizes a structure resulted from breaking an original symmetry, where the symmetry is defined in terms of an invariant in a system. Examples of such invariants include class structure (in the vulgar sense as in Section 4.2) and behavior (subtyping as discussed in Section 4.3).

In other words, a pattern represents a symmetry effect that is less symmetric than the symmetry cause, where the symmetry cause is produced by a programming language construct. Patterns precipitate from symmetries in response to both internal and external forces that are the analogy of instability.

A pattern is a design solution that language constructs fail to provide. A pattern language defines a composition law for composing patterns in a specific way to solve a larger design problem. A pattern is in relation to a symmetry that in turn is in relation to a geometric context: a symmetry group.

The formal aspect of the definition is necessary but not sufficient. The articulation of a pattern is also subject to a value system, and in particular to aesthetic and quality considerations. Among these considerations are human comfort, utility, beauty, durability, and maintainability.

This definition is simply a distillation of the findings of this paper, cast in a way that ties the group theoretic foundations with the vernacular definitions. We propose it as a foundation for further work in the formalization of software patterns.

One might use this definition to conclude that because the design patterns reflect different geometric contexts, they could never all be unified in a single pattern language. For example, the context for Observer and Memento is temporal symmetry while the context for most other patterns is more spatial. This contextual modeling might provide a framework for a pattern taxonomy that would be more useful than the current taxonomy (creational, structural, etc.) for the stated purpose of a pattern language: to create whole systems through a piecemeal growth process.

9 Conclusion and Acknowledgements

Other attempts to formalize patterns have striven for implementation automation. That is not our goal here, as automation of pattern assembly is an oxymoron from first principles. Our goal is to provide a formal basis for the characterization of patterns in specific contexts. For example, the symmetry theory foundation for patterns explains why multiple dispatch is a pattern in Smalltalk, and is not a pattern in CLOS. It explains why inheritance for subtyping is a symmetry, lacking the symmetry-breaking properties that are characteristic of patterns, even though Inheritance wrongly appears as a pattern in some collections [31]. This model may provide a foundation for legitimizing other patterns on the basis of temporal symmetry breaking models, even hopelessly non-spatial patterns.

This paper deals with patterns commonly associated with design. There may be other useful patterns of programming, such as indentation style and other modular constructs, that also exhibit symmetry and symmetry breaking and which are equally important to the success of software development.

Ralph Johnson provided initial feedback to the original draft and has continuously provided valuable insights and comments to various versions of the paper. We are also deeply indebted to Michael Benedikt, Ellie D'Hondt, Maja D'Hondt, Ed Remmel, Curtis Tuckey, Gottfried Chen, Edith Adan-Bante, Peter Mataga, Rachel Suddeth, Kevlin Henney, Neil Harrison, Rich Delzenero, Christoph Koegl, and Peter Grogono.

References

  1. Alexander, C., et al. A Pattern Language. New York: Oxford, ©1977.
  2. Alexander, C. The Nature of Order. Pending publication by Oxford, New York, New York. Citations quoted with permission.
  3. Alexander, C. The Timeless Way of Building. New York: Oxford, ©1979.
  4. Alexander, C. A Foreshadowing of 21st Century Art: The Color and Geometry of Very Early Turkish Carpets. New York: Oxford University Press, ©1993.
  5. Cook, W., and J. Palsberg. A Denotational Semantics of Inheritance and its Correctness. IN OOPSLA '89 Conference Proceedings, SIGPLAN Notices 24(10), 1989. New York: ACM SIGPLAN, p. 436.
  6. Coplien, J. Advanced C++ Programming Styles and Idioms. Reading, MA: Addison-Wesley, ©1992.
  7. Coplien, J. Software Patterns. New York: SIGS Publications, ©1996.
  8. Coplien, J. Space: The Final Frontier. C++ Report 10(3). New York: SIGS Publications, March 1998, 11-17.
  9. Coplien, J. Worth a Thousand Words. C++ Report 10(5). New York: SIGS Publications, May/June 1998, ff. 54.
  10. Coplien, J. To Iterate is Human, to Recurse, Divine. C++ Report 10(7). New York: SIGS Publications, July/August 1998, 43-48; 51.
  11. Coplien, J. Multi-Paradigm Design for C++. Addison Wesley, Reading MA. 1999. ISBN 0-201-82467-1
  12. Coplien, J. Take Me Out to the Ball Game. C++ Report 11(5). New York: SIGS Publications, May 1999, 52-8.
  13. Coplien, J. C++ Idioms Patterns. In Pattern Languages of Program Design 4. Reading, MA: Addison-Wesley, ©2000.
  14. Eden, A. H., J. Gil, A. Yehudai. A Formal Language for Design Patterns. 3rd Annual Conference on the Pattern Languages of Programs (Washington University Technical Report WUCS-97-07).
  15. Eden. A. H., J. Gil, A. Yehudai. Precise Specification and Automatic Application of Design Patterns. The Twelfth IEEE International Automated Software Engineering Conference (ASE 1997).
  16. Gamma, E., et al. Design Patterns: Elements of Reusable Object-Oriented Software. Reading, MA: Addison-Wesley, ©1996.
  17. Gordon, C. and N. Hindman. Elementary Set Theory. Hafner Press, 1975.
  18. Grenander, U. Elements of Pattern Theory. Baltimore, Maryland: Johns Hopkins University Press, ©1996.
  19. Hawking, S. A Brief History of Time. New York: Bantam, ©1996.
  20. Kappraff, J. Connections: The Geometric Bridge Between Art and Science. McGraw-Hill, 1990.
  21. Lippman, S. B., and J. Lajoie. C++ Primer. 3rd Ed. Addison-Wesley, 1998.
  22. Liskov, B. Data Abstraction and Hierarchy. SIGPLAN Notices 23,5, May 1988, p. 25.
  23. Mackay, A. L. Generalized Crystallography. Computers & Mathematics With Applications, 12B(1/2). Exeter, UK: Pergamon Press, 1986.
  24. Mannheim, P. D. Symmetry and Spontaneously Broken Symmetry in the Physics of Elementary Particles. In Computers and Mathematics with Applications, 12B(1/2). Exeter, UK: Pergamon Press, 1986, 169-183.
  25. Meszaros, G. Pattern: Half-Object plus Protocol (HOPP). In J. O. Coplien and D. Schmidt, eds., Pattern Languages of Program Design, Reading, MA: Addison-Wesley, ©1996, Chapter 8, 129-132.
  26. Meszaros, G. A Pattern Language for Improving the Capacity of Reactive Systems. In Pattern Languages of Program Design - 2. Reading, MA: Addison-Wesley, ©1998, p. 586, "Fresh Work Before Stale."
  27. Meyer, B. Object-Oriented Software Construction. Upper Saddle River, NJ: Prentice-Hall, ©1997.
  28. Rosen, J. Symmetry in Science: An Introduction to the General Theory. New York: Springer-Verlag, 1995.
  29. Senechal, M. Geometry and Crystal Symmetry. In Computers and Mathematics with Applications 12B(1/2). Exeter, UK: Pergamon Press, 1986.
  30. Stewart, I., and M. Golubitsky. Fearful Symmetry: Is God a Geometer? London: Penguin, ©1992, 1993.
  31. Tichy, Walter. Essential Software Design Patterns, http://wwwipd.ira.uka.de/~tichy/patterns/overview.html, n.d.
  32. Urmantsev, Y. Symmetry of System and System of Symmetry. Computers and Mathematics with Applications, 12B(1/2). Exeter, UK: Pergamon Press, 1986, 379-405.
  33. Weyl, H. Symmetry. Princeton University Press, 1952.
  34. Zhao, L, and T. Foster. Driver Duty Constructor: A Pattern for Public Transport Systems. In The Journal of Object-Oriented Programming 12(2), May 1999, 45-51; 77.