Patterns: A Way to Reuse Expertise
by
Linda Rising
AG Communications Systems

Abstract

There has been a sense in the software engineering community that we are continually reinventing the wheel. This phenomenon can be clearly seen in any large company, where projects go their own way, solving problems that are similar or identical to problems being solved by other projects, sometimes down adjacent corridors in the same building. It's easy to point at a lack of communication and the classic "not invented here" syndrome but the fact is, there hasn't been an appropriate communication medium for transferring knowledge. The widely applied code libraries did not even begin to tackle this problem.

The notion of a pattern is based on the work of building architect, Christopher Alexander, who captured solutions to recurring problems. When expertise is captured and shared with others, it also brings improved communication through a well-defined vocabulary of pattern names that reflect the successful solutions. There is a significant effort in the software community to apply this idea to problems and solutions in software development. Patterns provide a way to reuse expertise that can be used across domains at all levels of development.

Introduction

In the late 1970s, a book appeared, written by Christopher Alexander and his building architect colleagues. This book, A Pattern Language [1], presented Alexander's patterns, descriptions of solutions to problems in creating cities and towns, neighborhoods and buildings. [1, p. x]

Each pattern describes a problem that occurs over and over again in our environment and then describes the core of the solution to that problem in such a way that you can use this solution a million times over without ever doing it the same way twice.

Software professionals have also observed recurring problems and solutions in the engineering of software. There is clear evidence of patterns at all levels of software development, from high-level architecture to implementation, testing, and deployment. There is considerable work going on to apply this technology to software engineering. Patterns go a long way toward capturing what experts know, making it possible to share that knowledge with others.

A pattern is, on the surface, simply a form of documentation. Pattern authors document patterns they observe across many software projects. Experienced designers read these patterns and remark, "Sure, I've done that — many times!". The power of this kind of documentation is that knowledge, previously found only in the heads of experts, is captured in a form that is easily shared.

Patterns are not theoretical constructs created in an ivory tower; they are artifacts that have been discovered in multiple systems. It's an important element of patterns that the solution is one that has been applied more than twice. This "Rule of Three" ensures that the pattern documents tried and true applications, not just a good idea without real use behind it.

The approach calls to mind the notions of cohesion and coupling developed by Yourdon and Constantine [2] during many late Friday afternoon postmortem sessions, discussing lessons learned from past projects. The cohesion and coupling ideas captured qualities of real systems. The guidelines were not theoretical musings but were based on observations of capabilities of systems that made life easier for developers and maintainers. This is true for all patterns.

This article will give the reader a little background in patterns as preparation for the other papers in this special issue. We will start with an overview of patterns, then have a look at the pattern form with an example pattern, finally, a consideration of patterns and frameworks and another example. A list of references and URLs for more information is also included.

Patterns Overview

A book [3] co-authored by four individuals, often called the Gang of Four or GOF, was introduced to the software community at OOPSLA '94 (Object-Oriented Programming Systems, Languages, and Applications conference). The book documents twenty-three patterns recognized as providing accepted solutions for recurring problems in object-oriented design.

Even though no quantifiable results are available, teams familiar with patterns indicate that design and code in projects seems to have a new character. Design decisions are made more quickly, with trade-offs naturally included.

Since most of the activity in the patterns community has been tied to object-oriented development, most of the publications and pattern discoveries have been directed toward solving problems in that paradigm. However, the notion of patterns is not tied to any methodology or language.

Jim Coplien and Bob Hanmer have been involved in an interesting patterns experiment at AT&T (now Lucent Technologies). Management at AT&T were concerned about the future retirement or transfer of experts who had been part of the 4ESS™ switch, one of AT&T's large telecommunications switches. The directive to Coplien and Hanmer was to extract this expertise and capture it in patterns.

When Coplien and Hanmer shared some of the patterns from their 4ESS switch experience [4], many of them seemed very familiar. Leaky Bucket Counters, for example, is used on the GTD-5Ò switch we develop for GTE and other telephone companies. Reports like this demonstrate that patterns are much more than the artifacts of object-oriented design documented in the Design Patterns text [3]. This is a common misconception about patterns.

The 4ESS switch patterns are certainly not object-oriented; that is, they don't involve inheritance or polymorphism. The same can be said for the patterns we are discovering on the GTD-5, largely written in Pascal. This topic was an important one for AG Communication Systems. Initially, there was a concern that patterns would not be useful for developers working on the GTD-5 switch. We realize now that patterns can be written for any kind of software, for any domain, in any programming language.

At AG Communication Systems, we have documented patterns in customer interaction and system test [5]. Jim Coplien has created a body of patterns literature [6] concerned with organizational and process patterns. Alistair Cockburn [7] has written extensively in the area of risk management patterns. Perhaps these organizational patterns will be the most beneficial patterns of all and might, in the long run, have the greatest impact on our technology.

Patterns form a more flexible foundation for reuse. A handbook of best practice patterns could provide workable solutions for a given domain. A handbook like this would be particularly valuable for capturing domain expertise. Patterns also appear across domains. A group of investigators at Siemens AG has written a book of architectural patterns [8]. These are not specific to any particular domain but have wide application.

A pattern language is a collection of patterns that work together to solve problems in a given domain. The student of Alexander's pattern language realizes that each pattern solves a problem but it doesn't end there. The result of a pattern's use is not simply: our problems are solved. Each application of a pattern will create a new context where new problems must be considered. Those new problems require patterns for their solution and so on. Alexander begins by looking at the problems of high-level architectural design in developing a town or community and ends with patterns that solve lower-level problems, like Different Chairs and Pools of Light. As Alexander states [1, p. xiii]:

In short, no pattern is an isolated entity. Each pattern can exist in the world, only to the extent that 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.

Pattern Form

There are several pattern forms for documenting patterns. These differ but share the following elements. Facade, from the Design Patterns text [3], will be a running example to explain some of the elements of the pattern form. The name is an effective one. After the pattern has been explained, users discover that the name will call up the underlying problem and its solution.

Name
The name is a word or short meaningful phrase that describes the pattern. The name is extremely important, since it is used to reduce communication overhead. The pattern name, like the name of an algorithm or data structure, carries a lot of information, not because it is meaningful in itself but because of the underlying concept it represents. Those who understand this underlying concept can use the name as a short hand with others who, because of training or experience, have a similar understanding of the concept. For example, the name Binary Search carries information on the appropriateness of its use (only for sorted arrays) and performance (faster than a linear search). All developers assume this information. Everyone might not readily recall the implementation of a Binary Search but everyone should know where to find this information and be able to use it. The name of a pattern is a powerful mechanism for invoking ideas in the mind of the hearer.

In a design discussion, someone might suggest the use of Visitor. Everyone would recognize whether or not the choice was appropriate, given the inheritance hierarchies involved. The actual implementation might not be trivial and help from a reference might be required, just as for Binary Search. The use of the name, in both cases, enables discussion at a higher-level of abstraction and a better consideration of trade-offs to produce the best design. As with any other language, the meanings must be understood to communicate effectively.

Among the benefits of discovering and using patterns, the impact on communication is the most powerful. When teams have design discussions at a higher-level, the time spent in these discussions is reduced and product quality is improved as a result of incorporating solutions with proven records of success.

Communication improvement takes place not only within teams but across teams as well. Moving from one team to another should not involve re-learning design vocabulary. Everyone knows Binary Search. Everyone knows stacks and queues. Everyone should also know design patterns. The patterns enable implementers as well as designers. Instead of having continual consultation with the architects, a well-defined vocabulary will enable implementers to better understand the intent of the design.

Problem
This is the specific problem to be solved. For Facade, the problem is:

How can clients of a subsystem be shielded from the complexity of the interfaces of all the classes in the subsystem?

Context
The context explains the setting where the problem is found. For Facade, the context is:

A system that contains subsystems where dependencies exist between subsystems.

Forces
The forces are considerations that must be weighed to reach the best solution. The forces answer the question, "Why is this a hard problem?" For Facade, the forces are:

Partitioning a system into subsystems helps reduce complexity.
Subsystems often get more complex as the system evolves.
Lots of interconnections between subsystems make subsystem behavior difficult to understand and hamper reuse.

As the reader encounters the forces, there is a build-up of tension as the reader admits, "This is a harder problem than I realized!" This tension will be resolved by the solution.

Solution
This is where the essence of the solution is described, the components, their relationships and responsibilities — but no implementation. Other patterns can be referenced to provide solutions for sub-problems.

In a pattern the implementation is not specified. Just as software design is separate from details such as programming language, operating system, or hardware considerations, patterns are removed from particular settings, and can be used over and over. In our pattern form at AG Communication Systems, we include an Example section for sample code. This is to help the user understand the pattern, not to provide reusable code. The code can be reused, of course, but a design pattern is not restricted to a particular implementation, programming language or domain. For Facade, the solution is:

Provide a higher-level interface, a facade object, for the subsystem, which is simpler and easier to understand than the collection of interfaces to all the classes in the subsystem. Allow clients that must access individual subsystem objects to do so directly, bypassing the facade object.

This pattern is not limited to applications in object-oriented development. Many of us have used Facade in structured design. It is simply a module that enables simpler communication with a subsystem.

Resulting Context
This section contains a description of the state of the world after the pattern has been applied. This description should not be trivial; that is, it should not simply say that the problem has been solved. This part of the pattern should describe the impact on the user of applying the pattern. Potential users of the pattern can study this section to weigh the costs and benefits. In a pattern language, the resulting context of one pattern becomes the context for successive patterns that address new issues.

The resulting context for Facade is:

The facade object encapsulates subsystem functionality and makes the client interface simpler. It reduces coupling between clients and the subsystem components. Changing the subsystem is easier, since knowledge of the behavior is hidden in the facade. The facade interface should not prevent clients from accessing subsystem objects, so clients who continue to access subsystem details will have to be considered if there is any subsystem modification.

Patterns and Frameworks

Patterns in isolation don't provide the reuse benefit seen when collections of patterns work together in a framework. According to Ralph Johnson [9, p. 46]:

A framework…is more than just a pattern — it is also code. It is a reusable design expressed as a set of abstract classes (i.e., code) and the way that instances of those classes interact. Since it includes the way instances of those classes interact, it is the collaborative model or pattern of object interaction as much as it is the kinds of classes in the design.

Broker is an architectural pattern [8] that is the foundation for a framework developed in AG Communication Systems' Intelligent Network (IN) product development area. A team of designers who had just completed their training in design patterns developed the framework. They used their newly acquired expertise to create an architecture based on patterns that has been reused in several IN products. Here is a brief outline of this pattern.

Name
Broker
Problem
When a system is made up of distributed components, they need a way to communicate.
Context
You are working in a distributed, possibly heterogeneous, system with independent, cooperating elements.
Forces
Partitioning the system into independent components enables distribution.
Services to add, remove, exchange, activate, and locate components will be needed.
Applications that use an object should not have to be concerned with its physical location.
Solution
Add a broker component to decouple clients and servers. Servers register with the broker and clients access servers by sending requests to the broker.
Resulting Context
Clients do not need to know where servers are located. Servers can be moved without affecting client access.
The performance of the system may suffer as a result of the overhead of using the broker to access servers.

Conclusion

The idea behind patterns is simple, yet profound. Patterns capture knowledge that experts apply in solving recurring problems. What's reused when a pattern is applied is the knowledge of many experienced designers.

In a recent report of knowledge sharing [10, p. xiv]:

Teams of leading heart surgeons from five New England medical centers observed one another's operating-room practices and exchanged ideas about their most effective techniques. The result: a 24% drop in their overall mortality rate for coronary bypass surgery, or 74 fewer deaths than predicted.

Metrics like this show the benefit of sharing expertise. Documenting solutions helps all of us improve. As Weinberg has wisely noted, "None of us is as smart as all of us!" He was talking about the review process but his observation is certainly appropriate here. When we share our knowledge, we can all build on that knowledge and improve instead of re-inventing solutions over and over again.

Patterns are not a "silver bullet." They will not address all reuse issues or single-handedly solve the software crisis. They will not transform novices into experts but they provide a simple, intuitively appealing solution for problems that keep appearing over and over again. Patterns — an approach to reuse that has been used as long as novices have been learning from experts.

More Information on Patterns

Information on the several patterns listservers, patterns conferences, published works, and other patterns home pages can be found on the web. Here are some good places to start:

Acknowledgments

Thanks to Dr. Ram Batni at AG Communication Systems for proposing the idea of this feature topic on design patterns in communications software. Thanks to the reviewers of this paper: Robert Hanmer, John Letourneau, and Lizette Velazquez, all of Lucent Technologies. Their careful reading and valuable comments have helped produce an improved version of this paper.

References

  1. C. Alexander, et al., A Pattern Language, New York: Oxford University Press, 1977.
  2. E. Yourdon and L. L. Constantine, Structured Design, Englewood Cliffs, NJ: Prentice-Hall, 1978.
  3. E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software, Reading, MA: Addison-Wesley, 1995.
  4. M. Adams, J. Coplien, R. Gamoke, R. Hanmer, F. Keeve, and K. Nicodemus, "Fault-Tolerant Telecommunication Patterns," Pattern Languages of Program Design 2, Reading, MA: Addison-Wesley, 1996, J. M. Vlissides, N. L. Kerth, and J. O. Coplien, eds, pp. 549-562.
  5. D. DeLano and L. Rising, "A Pattern Language for System Test," Pattern Languages of Program Design 3, Reading, MA: Addison-Wesley, 1997, R. Martin, D. Riehle, and F. Buschmann, eds, pp. 503-525.
  6. J. O. Coplien, "A Generative Development-Process Pattern Language," Pattern Languages of Program Design, Reading, MA: Addison-Wesley, 1995, J. O. Coplien and D. C. Schmidt, eds., pp. 183-238.
  7. A. Cockburn, Surviving Object-Oriented Projects, Reading, MA: Addison-Wesley, 1998 and http://members.aol.com/acockburn/riskcata/risktoc.htm
  8. F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad, and M. Stal, Pattern-Oriented Software Architecture, A System of Patterns, New York: John Wiley & Sons, 1996.
  9. R. E. Johnson, "Patterns of thought: Patterns and Frameworks," ROAD, March-April 1995, pp. 46-48.
  10. T. H. Davenport and L. Prusak, Working Knowledge: How Organizations Manage What They Know, Boston, MA: Harvard Business School Press, 1998.


© 2001 AG Communication Systems, used with permission.