Advanced Design Patterns

Presented by: Yair Alan Griver
Chief Information Officer
Flash Creative Management, Inc.
Phone: (201)-489-2500
Email: http://www.flashusa.com/
Special thanks to Steven Black of SBC/UP for the use of materials

Introduction

A pattern is a recurring solution to a particular problem in a given context. A design pattern is a general abstraction of the solution across the range of problems and contexts where the pattern is appropriate.

Design patterns have names, and knowing (and agreeing) on their names and meanings leads to a pattern language which is useful in conveying the abstractions among ourselves. The shared vocabulary makes patterns an excellent vehicle for conveying design experience.

Most catalogued software design patterns, when applied under appropriate conditions to solve the correct sort of problem, have known tendencies to be stable, scaleable, and coherent. These patterns are just now being identified, analyzed, and cataloged.

When properly catalogued, design patterns define the parts, collaborations, and responsibilities of classes and instances. The nice thing is they abstract the subsystem above the level of classes, instances, and code. Patterns are all about architectures, their component structures, and all their nuances.

So patterns serve as a guide to the sensible design of software building blocks, and they help us better communicate and cope. Anyone who has used a napkin to sketch the workings of a software system knows that a picture is worth a thousand words. Over the next two days, it should be come clear that a correct word can be worth many pictures.

A note on pattern form: There are many ways to communicate patterns, and there are several conventions about how patterns should be conveyed on paper. In this document I am not concerned about following one or the other particular convention. I am much more interested in conveying how design patterns can be recognized and implemented.

A note on this document: This paper is assembled from my personal research notes as I work on a book on object-oriented design patterns for Addison Wesley. As such, it is to be considered a working document, and I apologize in advance for its lack of rigor and for any inaccuracies and errors.

Notation

In this document we’ll use Rumbaugh OMT notation. Here are a few important elements of this notation.

Figure 1. Abstract classes or abstract elements within classes have italic labels. Concrete classes use regular text.

Figure 2. Inheritance is symbolized with a triangle. In this case, the concrete classes inherit from the abstract class.

Figure 3. The relationship type is determined by the arrow base, and cardinality is determined by the arrow head. Dashed lines usually imply creation.

Figure 4. Implementation details are presented in a Windows-like window.

Exercise:

Figure 5. As an exercise, interpret this diagram.

Pattern 1. Proxy (Extends Decorator)

Provide a surrogate or placeholder for another object to control access to it.

Problem How to provide correct and/or efficient access to an object that may be resource intensive or otherwise require protection?
Context A client needs the services of an object, but direct access is technically possible but questionable.
Forces –Some objects are expensive and cannot be instanced at the outset or, once instanced, perpetually held in memory.

–Some objects require security access, while others may be subject to hostile attack.

–Some objects may have complex protocols and efficient programming requires a more simplified interface.

Solution Make a component’s clients communicate with a representative rather than with the component itself.
Resulting Context Three actors: The client (as usual), the original object (as usual), and an intervening object (the Proxy) which serves as a placeholder for the original object and forwards requests as appropriate.


Uses for the Proxy Pattern

There are many uses for the Proxy pattern. A Remote Proxy encapsulates and maintains the physical location of the original object. A Protection Proxy protects the original from unauthorized access. A Cache Proxy uses a data area to temporarily hold results, and has strategies to maintain and refresh the cache. A Synchronization Proxy controls multiple simultaneous client accesses. A Counting Proxy is useful to add reference counting mechanism to classes so that unused objects can be destroyed in a timely fashion. A Virtual Proxy loads missing parts of the original on demand, thus delaying the consumption of resources until they are needed. A Firewall Proxy protects the original from potentially hostile access.

Of course, you could combine two or more of the above roles. We’ll construct a Proxy or two during the session.

Pattern 2. Chain of Responsibility

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

Chain Of Responsibility patterns decouple a message sender from its receiver by giving many objects a chance to handle the message. The identity of the eventual service-providing object(s) may not be known to the sender, so the Chain Of Responsibility routes the request until it is adequately handled.

A good place to find Chain Of Responsibility patterns is within easily traversed hierarchies, like containership. With containership the logic is usually simple: “If an object can’t handle a request, then delegate it to its Parent.” Help systems, among others, frequently use this pattern to invoke context-sensitive help. Chain of responsibility can be implemented without containership by using object pointer registration schemes.

Implementing a Chain of Responsibility Pattern in Microsoft FoxPro

Here’s a way to structure a Chain Of Responsibility: When in doubt, delegate to THIS.PARENT. In the example below, nested boxes delegate their Click() event upwards until it is handled. Don’t be fooled by all this code, for most of it just sets up the example. The only code you really need is in the Click() methods of the container classes. The code follows, starting on the next page.

xx=CREATE(“Form1”)
xx.Show()
READ EVENTS
DEFINE CLASS form1 AS form
    Height   = 300
    Width    = 448
    Caption  = “Form1”
FUNCTION INIT()
*-- Add six nested containers
THIS.AddObject( “FirstContainer”, “ctnr”)
*-- Style note: nested WITH...ENDWITH statements.
WITH THIS.FirstContainer
.AddObject( “SecondContainer”, “ActiveCtnr”)  && TAKE NOTE!
  WITH .SecondContainer
  .AddObject( “ThirdContainer”, “ctnr”)
    WITH .ThirdContainer
      .AddObject( “FourthContainer”, “ctnr”)
      WITH .FourthContainer
        .AddObject( “FifthContainer”, “ctnr”)
        WITH .FifthContainer
          .AddObject( “SixthContainer”, “ctnr”)
        ENDWITH
      ENDWITH
    ENDWITH
  ENDWITH
ENDWITH
ENDDEFINE

Sample 1. The code above generates nested containers of class Cntr as in the illustration below.

Figure 6. Nested containers. Here the gray container handles the Click() event of all its inner members.

DEFINE CLASS ctnr AS container
Name = “ctnr”
FUNCTION INIT
	*-- Container placement
	THIS.Top    = 20
  THIS.Left   = 20
	THIS.Width  = THIS.PARENT.Width-40
	THIS.Height = THIS.PARENT.Height-40
	THIS.Visible= .T.
ENDFUNC
FUNCTION Click
	*-- the purpose of this method is 
	*-- by default to pass the click 
	*-- event to THIS.PARENT.
	IF TYPE( “THIS.Parent”)= “O” 
		*? Error trap this.
		THIS.Parent.Click()
	ENDIF
ENDFUNC
ENDDEFINE

DEFINE CLASS ActiveCtnr AS Ctnr
	BackColor = RGB(192,192,192)   && For your viewing pleasure
  FUNCTION Click
  WAIT WIND THIS.Name + “ is handing the message” NOWAIT
  *-- If the search must stop here, omit the following 
  Ctnr::Click()
  ENDFUNC
ENDDEFINE

Sample 2. Class definition for Ctnr and ActiveCtnr. Note that THIS.PARENT.DoHelp() is invoked upon no joy in THIS.DoHelp().

Other Ways of Implementing Chain of Responsibility Patterns

In our example we use PARENT referencing to algorithmically reckon the next successor in the chain. There are other ways to do it, including direct referencing, where each object keeps pointers to one or more successors. Assigning objects to these pointers must be managed, of course, and care must be taken to avoid both circularities and unhandled requests.

Chain Of Responsibility can also be built with a handler class that broadcasts the message to a sequence of objects until the message is satisfactorily handled. A variant of this uses object registration mechanisms to maintain the list and sequence of objects to be called.

You may need to pass parameters along the chain. This can be problematic if a variety of classes participate in the successor chain, especially if a handler is involved and the identity of the receiver classes isn’t known for certain. In this case, it’s most helpful to standardize message passing using objects instead of parameters. Like always, a mature and predictable programming interface helps.

Finally, it’s useful to note that a Chain Of Responsibility doesn’t need to end when a message is handled by a receiver in the chain. It may well be desirable for the message to be broadcast to many objects regardless.

Pattern 3. Strategy-INTL Example

According to the GOF, the intent of the Strategy pattern is: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

Problem Not all localizations are alike. For example, a port from the US to the UK or Canada probably needs only minor interface adjustments, along with perhaps local currency support. A port from the US to Germany, on the other hand, requires extensive interface along with, potentially, localizing images and data sources. A port further afield may require changing fonts and most of the other localizable things. How to do this?
Context The application localization must be configurable, in the field, on the fly.
Forces –The user must be able to configure localizations to suit needs.

–The user should be able to create new localization strategies without much difficulty.

Solution Separate individual localization tasks into atomic processes, then give each process the same interface so as to make them interchangeable. Give the controlling process a clean inteface for loading strategies, and design the process to call each loaded “strategy” in turn.
Resulting Context A modular set of strategies that can be applied as appropriate. In the case of INTL, certain parts of the localization strategies are so common-lookups in STRINGS.DBF for example-that this capability was migrated up the hierarchy to avoid loading redundant capabilities in each strategy.
Rationale Separating the localization tasks into separate strategies, and creating a mechanism to iterate through the loaded strategies, allows for much configuration flexibility. The downside is a performance penalty arising from the some inevitable common elements and from an increase in messaging traffic.

Figure 7. The INTL class Strategy branch.

Pattern 4. Iterator-INTL Example

An Iterator provides a way to sequentially access all the elements of a structure independently of the structure type. The need for iterators comes up all the time.

There are many sorts of structures to iterate in Microsoft® Visual FoxPro®. Tables and arrays are things we frequently need iterate. Other structures include FoxPro’s native structures (which are also tables) as well as objects nested, often several layers deep, within containers.

INTL uses an iterator as part of its INTLTOOL.PRG utility.

Problem Visual FoxPro has an open architecture – Its metadata is stored in standard FoxPro tables. How to process a Visual FoxPro project file (.PJX) in order to programmatically access all the files of a given type in an application. In the context of INTL, we may need to process a whole project for a variety of reasons, like auditing it for strings, message calls, international infelicities, or other issues.
Context The user wishes to run a batch-process on one or all of an application’s metadata. It would be nice to have a clean interface to do this.
Forces –The Visual FoxPro .PJX structure points (albeit somewhat cryptically) to each element in the project.

–The project elements are readable either as FoxPro data structures or ASCII text files.

Solution Create an iterator class whose specialty is to traverse FoxPro structures. Subclass this iterator for specific specialties (creating classes like ScreenIterator or MenuIterator or ReportIterator).
Resulting Context A hierarchy of classes that can be used to reliably traverse metadata. Note that in INTL, the action to accomplish upon traversal is separate from the traversal process. See the Visitor pattern on page 9.
Rationale Once the iteration process is abstracted, then generic interfaces can be used to traverse a wide variety of structures. For example, the difference between traversing an array, a table, or a containership hierarchy can be safely hidden. This is very useful because it hides the nuance of traversal mechanics, allowing us to focus instead on the process that requires the traversal.

Figure 8. The INTL Iterator class hierarchy. Each class specializes in iterating a particular structure. This class is concerned only with Visual FoxPro metadata tables.

Pattern 5. Visitor-INTL Example

The role of a Visitor is to represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.

Problem In the context of localizing applications, we occasionally encounter the need to mix two separate actions, like 1) traversing a structure and 2) what to do at each step in the traversal. We’ve already discussed the Iterator pattern (page 8)-why not just subclass iterators as needed? The reason this is undesirable is mostly because this would add a new “dimension” to the iterator class hierarchy, which leads quickly to class explosion. So the problem can be restated as: How to endow classes with custom behavior without risking an explosion in the class hierarchy.
Context We need to iterate Visual FoxPro structures in order to audit the source or to perform specific actions like enabling report files for multilingual support. Other tasks are sure to arise in the future. How to rig this?
Forces –The iterator class is stable and specialized for iteration.

–The desire to alter process behavior tempts us to alter the iterator class by subclassing.

–A class explosion isn’t desirable.

Solution Create a class whose function is to encapsulate process mechanisms. This class is the visitor class. Then create an interface protocol such that the visitor class can visit targets, and so the targets can accept these visitors. Thereafter allow these classes to be combined using this interface.
Resulting Context The result is a desirable separation of chores between 1) traversal and 2) what to do upon traversal.
Rationale Whenever possible, it’s desirable to avoid a geometric explosion in the class hierarchy because of non-class related variants. For example, if we exclude multiple-inheritance options, the combination of five iterator mechanisms with three behavior variants can lead to 15 different classes with potential for much duplication between them. Separating both the traversal and behavior mechanisms is a tidy way to accommodate the situation.

Figure 9. The INTL Visitor class hierarchy. These visitors control the Iterator classes.

Pattern 6. Hook Operations

Problem Provide a consistent and flexible mechanism for implementers to extend software.
Context Toolkits and frameworks are composed of general-purpose classes that are intended by their creators to be adapted by others in the future. Toolkits provide for code reuse, while frameworks provide for architectural reuse. In both cases, flexibility and extensibility are virtues. How to best provide this flexibility?

Subclassing is the usual way toolkits and frameworks are meant to be adapted. Typically the original classes are kept pristine, and implementation-specific changes are made to subclasses. Adaptation by subclassing, however, presents special problems-source code, and specialized user knowledge, are required.

Adaptation by subclassing can sometimes create difficult upgrade, support, and maintenance situations. Moreover, the class creators, aware of these difficulties, are constrained in future releases to altering their product so to not pose problems for legacy subclasses that they know little about.

Hook operations are an alternative to subclassing. Hooks are places within procedures or methods where user-defined adaptation is specifically designed to take place. A hook operation is the code that invokes the hook. The Hook Operation design pattern describes generic interfaces and methodologies for adapting software using hooks.

For example, consider a user interface component with the click method in Listing 1. The built-in click method is preceded by a hook called by THIS.ClickHook(). The ClickHook() method is a good place for users to place custom processing in subclasses without polluting the built-in Click behavior.

FUNCTION Click
THIS.ClickHook()
WAIT WINDOW “Built-in Click Method”
<100 lines of code>
ENDFUNC

Hooks usually do nothing by default; they are used by exception. A hook is a separate and distinct method from the one that provides built-in class behavior. The hook is invoked in such a way that the built-in behavior can be enhanced or replaced without polluting the original source and without altering the built-in behavior provided by the class.

Forces The class must be enhanced in a consistent manner without prior knowledge of implementation.
Solution Provide hooks for known areas that must be enhanced.
Resulting Context The result is a standardized approach for enhancing functionality.
Rationale Subclassing may not provide the functionality that we know we will require. This approach allows us to add code without affecting existing code.

Applicability

Hooks are appropriate in situations where you want software to be adaptable. Two occasionally conflicting forces determine where and how hook operations should be used. On one hand, hook operations are most valuable at critical junctures in a process. On the other hand, usability suggests that hooks should be placed at predictable junctures.

Critical junctures are adjacent to where significant transformations occur. For example, in an accounting application, the spot where transactions are committed could be considered a critical juncture. Critical junctures are usually difficult to reliably identify, and difficult to document. Moreover, a trivial juncture in one framework implementation may be a critical juncture in a different implementation.

Predictable junctures are architecturally predictable spots. For example, a predictable juncture could be defined to be where methods begin or end. Predictable junctures are sometimes (but not always) located close to where adaptation is likely to be desired. This location compatibility is a function of program granularity: The briefer the method, the more likely a predictable juncture is proximate enough to a critical juncture to be useful. In general, predictable junctures are easy to identify and document.

The tradeoff between critical and predictable junctures is a user education issue. If implementers are not able to identify hook operations are placed, then they won’t be able to engineer the hooks they require.

A good question now arises: how to optimize messaging for flexibility? To answer this, let’s first list what sort of flexibility might be desirable when we execute a method or a procedure:

It is worth noting that hooks usually do nothing by default. They are placed by the software’s creators to be used by exception as individual implementation needs arise.

Structure

A number of structures are possible, depending on how the hook is engineered.

Internally fulfilled hooks

When hooked objects handle their own hooks, the structure illustrated in Figure 1 is typical. Here the hook methods are implemented by subclassing and then coding the subclass’s hook method. This structure is similar to that of the Template Method design pattern, except that algorithmic steps defined in the template method specifically provides for hook operations.

Externally fulfilled hooks

When hook operations can delegate to hook objects, this can leads to a many possible structures. Figure 2 shows a case where the hook objects are kept in separate hook classes, and Figure 3 shows a case where the hook class is a superclass of the hooked class.

Figure 1: Self-sufficient hooks have a structure similar to that of the Template Method design pattern.

Figure 2: Supporting hooks are separate hook objects, here shown as separate classes from those they adorn.

Figure 3: Hooks and Hooked objects can share the same interface, which implies that they can share the same class hierarchy. This is very handy from a maintenance perspective since the interfaces remain automatically in synch.

Participants

There are essentially two participants in the hook operation pattern.

Collaborations

Consequences

The advantages of Hook Operations include:

Some of the disadvantages are

Implementation

Future toolkit and framework implementers may wish to run a pre or post-processes in addition to a given standard method. For example, an implementer may wish to pre-process the click event of a “Save” button to ensure the connection is still active, or to log the action, or check security, or perform some application-specific validation, and so on. Also, the ability to override the standard method (something like NODEFAULT) is very handy.

Listing 2 shows a simple call to a pre-process hook. This example uses the common convention of naming the pre-process with the prefix “pre”.

FUNCTION Click

  *-- Pre-process hook 

  THIS.PreClick() 

  WAIT WINDOW “Click” 
  <100 lines of code>
ENDFUNC

Listing 2. A pre-hook followed by standard method code.

Listing 3 shows a more flexible configuration, where the pre-processing return value controls the standard method execution. This is a crude NODEFAULT-like implementation, controlled by the pre-hook’s return value.

FUNCTION Click

  IF THIS.PreClick() 

    WAIT WINDOW “Click” 
    <100 lines of code>

  ENDIF

ENDFUNC

Listing 3. A pre and post-hook controls the execution of the standard method hook.

Listing 4 shows a variant of Listing 2, except here a post-processing hook, using the conventional “post” nomenclature, is used.

FUNCTION Click
  WAIT WINDOW “Click” 
  <100 lines of code>

  *-- Post-process hook 

  THIS.PostClick() 

ENDFUNC

Listing 4. A post-hooked Click hook.

Using pre- or post-hooks has the following huge advantage: By subclassing a standard class and modifying the pre or post-hook methods, you are not changing the original default behavior of the class methods. You are changing methods that are specifically designed for user-defined use. Thus, you avoid some of the tricky upgrade compatibility problems that may arise when the class creator or vendor makes new versions available.

As you may have guessed, pre and post-hooks can be combined, as shown in listing 5, to achieve flexibility on both sides of the standard method.

FUNCTION Click

  THIS.PreClick()  && Pre-hook

  WAIT WINDOW “Click” 
  <100 lines of code>

  THIS.PostClick() && Post-hook

ENDFUNC

Listing 5. Pre and post-hooks surround a standard method. If you intend this method to be subclassed, then avoid this!

Combining pre and post-hooks, as in listing 5, is not recommended. The reason for this arises upon subclassing. If you subclass the click method of listing 5, then use DODEFAULT() or the scope resolution operator (::) to invoke this parent method, then you’ll fire both the pre and post-hook at that point. Depending on the hooks, this can cause unexpected results.

How, then, to provide hooks both at the beginning and at the end of a particular process? It’s easy if you use a multi-part process. For example, consider a hookless component whose Click() calls a particular method, as in listing 6.

DEFINE CLASS HooklessProcess AS CommandButton
  FUNCTION CLICK

    DO THISFORM.SomeMethod()

  ENDFUNC
ENDDEFINE

DEFINE CLASS MyForm AS FORM
  ADD OBJECT oCmd AS HooklessProcess

  FUNCTION SomeMethod

    * << Your code here >>

  ENDFUNC

ENDDEFINE

Listing 6, a button without hooks.

Listing 7 shows how the code in Listing 6 can be modified so the "pre" hook is launched by the commandbutton, and the "post" hook is launched at the end of the method invoked by the command button. The process is thus neatly segmented into two distinct phases: The “event” phase, which is hooked, and controls the invocation of the “method” phase, which is also hooked.

DEFINE CLASS FullyHookedProcess AS CommandButton
  FUNCTION CLICK

    THIS.PreClick()  && The "Pre" hook

    THISFORM.SomeMethod()
ENDDEFINE

DEFINE CLASS MyForm AS FORM
  ADD OBJECT oCmd AS FullyHookLessProcess

  FUNCTION Somemethod
    << Your code here >>

    THIS.PostSomeMethod()  && The "Post" hook

  ENDFUNC
ENDDEFINE

Listing 7, a component with a hook before calling a Click implementation method. The Click implementation method contains its own hook at its conclusion.

You can abstract this hooking process, and recreate it easily, with the following rule of thumb:

Thus you have, in effect, a hook on the way in, and another one on the way out.

Visual FoxPro Example

Here is an illustrative example of the benefits of hooks. Here we’ll hook the RightClick() method of a textbox to provide a context sensitive popup menu. In practice you could hook all the common methods of all your base classes to do a variety of things.

The class definition, complete with its seeded RightClick() method, looks like this:

***************************************************
*-- Class:        appTextbox
*-- BaseClass:    Textbox
DEFINE CLASS appTextbox AS Textbox

  *-- Reference to a hook object
  ohook = .NULL.

  PROCEDURE RightClick
    *-- Delegate to any hook
    IF ! ISNULL( THIS.oHook)        AND ;
      TYPE( "THIS.oHook") = "O"     AND ;
      PEMSTATUS( THIS.oHook, "RightClick", 5)

       _BOX= .T.
       THIS.oHook.Rightclick()

       IF ! _BOX
         RETURN
       ENDIF

    ENDIF
  ENDPROC
  
  FUNCTION Release
    *-- It’s always wise to clean up your pointers
    THIS.oHook= .NULL.  
    RELEASE THIS
  
ENDDEFINE

Listing 8, a textbox with a RightClick hook.

Here’s a RightClick()-seeded hook object that works extremely well with textboxes and edit boxes to bring up a handy edit menu:

DEFINE CLASS lblmousehook AS label
  Caption= "MouseHook"
  Name   = "mousehook"

  PROCEDURE RightClick
    *-- Bring up a handy edit tools menu
    DEFINE POPUP shortcut SHORTCUT RELATIVE FROM MROW(),MCOL()
    *-- Cut
    DEFINE BAR _med_cut OF shortcut PROMPT "Cu\<t" ;
      KEY CTRL+X, "Ctrl+X" ;
      MESSAGE "Removes selection and places it onto the Clipboard"
    *-- Copy
    DEFINE BAR _med_copy OF shortcut PROMPT "\<Copy" ;
      KEY CTRL+C, "Ctrl+C" ;
      MESSAGE "Copies the selection onto the Clipboard"
    *-- Paste
    DEFINE BAR _med_paste OF shortcut PROMPT "\<Paste" ;
      KEY CTRL+V, "Ctrl+V" ;
      MESSAGE "Pastes the contents of the Clipboard"
    *-- Select All
    DEFINE BAR _med_slcta OF shortcut PROMPT "Se\<lect All" ;
      KEY CTRL+A, "Ctrl+A" ;
      MESSAGE "Selects all text or items in the current window"
    *-- Clear
    DEFINE BAR _med_clear OF shortcut PROMPT "Cle\<ar" ;
      MESSAGE "Removes the selection and does not place it onto the Clipboard"
    ACTIVATE POPUP Shortcut
ENDDEFINE

Listing 9, a usable RightClick() hook usable with code in Listing 6.

To set up this basic hook do the following:

oForm= CREATE("MyForm")

oForm.AddObject( "oTxtbox", "appTextBox")
oForm.AddObject( "oMouseHook","lblMouseHook")
oForm.otxtbox.Visible= .T.
oForm.otxtbox.oHook= oForm.oMouseHook
oForm.Caption= "RightClick this textbox"
oForm.Show()
READ EVENTS

Listing 10, Code to set up the RightClick() extended hook example.

When you RightClick over the textbox, control is passed to the hook, which invokes a context sensitive shortcut menu. Two things to draw from this example:

Appendix 1. Selected Reading, Sites, and Conferences

Reading

Alexander, C., et al. A Pattern Language. New York: Oxford University Press, 1977. ISBN 0-19-501919-9.

Alexander, C., et al. A Timeless Way of Building. New York: Oxford University Press, 1978.

Brooks, F., (1975 and 1995) The Mythical Man Month. Reading, MA. Addison Wesley. ISBN 0-201-83595-9.

Buschman, F., and Meunier, R. (1995) A System of Patterns. Chapter 17 (p. 325) in a compilation work by Coplien, J, and Schmidt, D (1995) Pattern Languages of Program Design. Reading, MA. Addison Wesley. ISBN 0-201-60734-4.

Buschman, F., Meunier, R., Rohnert, H., Sommerlad, P., and Stal, M. (1996) A System of Patterns. West Sussex, England. John Wiley & Sons. ISBN 0-471-95869-7.

Coad P., North, D., and Mayfield, M., (1995) Object Models: Strategies, Patterns, and Applications. Prentice Hall. ISBN 0-13-108614-6. Also a helpfile: STPTHLP.ZIP in CIS.CaseForum, Lib 3.

Coplien, J., Advanced C++ Programming Styles and Idioms. Reading, MA: Addison Wesley, 1992.

Coplien, J., and Schmidt, D. (1995) Pattern Languages of Program Design. Reading, MA. Addison Wesley. ISBN 0-201-60734-4.

Gamma, E., Helm, Observations on Observer, Dr. Dobb’s Sourcebook, September/October 1995.

Gamma, E., Helm, R., Johnson, R., and Vlissides, J. (1994) Design Patterns, Elements of Object Oriented Software. Reading, MA. Addison Wesley. ISBN 0-201-63361-2

Hay, D. (1995) Data Model Patterns: Conventions of Thought. Dorset House.

Helm, R., and Gamma, E. The Courrier Pattern. Dr .Dobb's Sourcebook Jan/Feb 1996. Miller Friedman Inc, San Francisco.

Juancarlo, Anez. (1995) A Perfect Fit. Windows Tech Journal, September 1995, Oakley Publishing Company, Springfield, OR.

Pree, W. (1995) Design Patterns for Object Oriented Development. Reading, MA. Addison Wesley and ACM press. ISBN 0-201-42294-8.

Rohnert, Hans, PLOP 96 Conference Proceedings, Addison Wesley (1996).

Vlissides, John, Seven Habits of Successful Pattern Writers, C++ Report, Vol 7 no 9, November-December 1995, SIGS publications, New York NY.

Web sites

The Cunningham and Cunningham, Inc., homepage, http://c2.com has a description of pattern history, a description of the Portland pattern form, guidelines for writing patterns in Alexander's style, and several patterns and pattern languages and links to other sites. Of particular interest here is http://c2.com/cgi/wiki which is a growing repository of pattern contributions from hundreds of interested developers.

The patterns homepage: http://st-www.cs.uiuc.edu/users/patterns/patterns.html Maintained by Richard Helm is a great place to start, with many links to choose from.

http://st-www.cs.uiuc.edu/users/johnson/ is maintained by Ralph Johnson.

There’s a good pattern discussion and FAQ at http://gee.cs.oswego.edu/dl/pd-FAQ/pd-FAQ.html

Upcoming conferences

UP-An International Workshop On Using Patterns, http://www.panix.com/~k2/up.html, Friday, March 7th to Sunday, March 9th, 1997. Location: Mohonk Mountain House. About 2 hours from New York City or Albany.

EuroPLOP ‘97, Second European Conference on Pattern Languages of Programming, July 10 - 12, 1997, Kloster Irsee, 87660 Irsee, Germany. http://www.cs.wustl.edu/~schmidt/EuroPLoP-97.html

PLOP ’97, "Pattern Languages of Programs", September 2-5, 1997, in Allerton House, Monticello, Illinois, USA . http://st-www.cs.uiuc.edu/~hanmer/PLoP-97.html

Appendix 2. Selected FAQs About Patterns

What else can patterns be applied to?

Existing software-related examples include:

What's the difference between a pattern and a coding idiom? A design? One or more OMT or UML diagrams? A use case? A protocol? An algorithm? A heuristic? An architecture? A coding standard? A coding style? A development method?

A pattern may be mainly about one of these things, but the thing alone does not comprise a pattern. A pattern describes how and why any of these may apply in a given development context, along with guidance for applying them.

What's the difference between a pattern and a class? A reusable component? A parameterized (template) class? A class library or package? A framework? A tool? A code generator?

A pattern is not an implementation. It describes when, why, and how to go about creating an implementation or other engineering product. Some (not many) solutions are amenable for description via implementations (as classes, frameworks, tools, or whatever) that provide developers with just about everything they would need to know or do. Even so, the code itself is not the pattern.

What's the difference between a pattern and How-To guide?

The solution described in a pattern may be phrased as a series of steps similar to those seen in How-To guides and cooking recipes. But again these steps form only one aspect of a pattern. Also, patterns aspire to greater scope and generality of context, and greater authoritativeness in identifying and resolving forces than seen in typical How-To guides.

Why should I use patterns?

For the same kinds of reasons that you should reuse good code: Benefiting from the knowledge and experience of other people who have put more effort into understanding contexts, forces, and solutions than you have done or want to do. Further, patterns can be more reusable than code, since they can be adapted so that you can build software to address particular special circumstances that cause you to be unable to reuse an existing component.

Patterns also give developers common sets of names and concepts for dealing with common development problems, thus enhancing communication.

Wouldn't it be nice to have some patterns-based CASE tools?

Maybe, but patterns are about communicating from one person to another. If the medium enhances communication with other people it is good. If it merely makes the machinations of the patterns executable by a computer it isn't.

Why aren't there more patterns about [WHATEVER]?

Because you haven't written them. If you're interested, you more than likely know something, and if you know something you can write patterns.

How do I go about writing a pattern?

Here are some common recommendations:

How can we institutionalize the use of patterns where I work?

Common recommendations include:

Are patterns over-hyped?

Of course. It is impossible to avoid.

© 1997 Microsoft Corporation. All rights reserved.

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.

This document is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.

Microsoft, FoxPro, and Visual FoxPro are registered trademarks of Microsoft Corporation.

Other product or company names mentioned herein may be the trademarks of their respective owners.