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
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.
Figure1. 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.
We’ll spend considerable time examining the Bridge pattern. This for two reasons.
Problem | To achieve reuse, some classes need to adapt either their implementations, their interfaces, or both. How to structure a class so that either (or both) can be easily modified? |
Context | You are designing a new class, or adapting an existing class to make it more reusable. You anticipate future extensions to object's form or function and you want to avoid extending a class hierarchy for the sake of new implementations. Perhaps you'd like to choose a specific behavior at run-time. |
Forces |
á The existing codebase may constrain what we can do with a class’s implementation. á Reuse could mean reuse by other systems that may expect or require a different interface than the one currently provided by our existing class. á We may need to adapt a class’s interface, implementation, or both. |
Solution |
Decouple an object's public interface ("form") from its implementation (its "function"), using two (or more) objects where otherwise one might less flexibly suffice. Separate a class’s interface from its implementation by making each a separate but tightly coupled objects. This way each can be varied independently of the other. The workings among the players in a Bridge should be direct and simple: the interface object forwards client requests to the appropriate implementation object. Tight coupling within the Bridge structure is both common and desirable. The tight coupling is much easier to manage when all the implementation objects come from the same class, as illustrated in the Codebook example illustrated below. |
Resulting Context | A Bridge is a decoupling of an abstraction (interface) from its implementation so the two can vary independently. Bridges are scale-independent structures that apply in many object oriented situations. A Bridge also serves as an atomic element player in other design patterns. |
Rationale |
The usual way to manage the requirement for different interface or implementation is by extending the class hierarchy using inheritance. After all, inheritance is usually the first mechanism most folks use to reuse their classes. And why not? In the early going, inheritance is always a big success. At the limit, however, inheritance leads to sclerosis-inheritance doesn't scale particularly well. Simple, single-object inheritance binds interface and implementation-you only have one package to transform into a subclass. This means that interface and implementation aspects cannot be independently varied without extending the class hierarchy. But class hierarchies naturally loses their inherent adaptability with size and as the number and variety of clients increases. Why?-side effects, partly. The probability of change side-effects in clients increases with the number and variety of those clients, and correspondingly with the current state of the hierarchy. In a giant class hierarchy, making a small change near the top can potentially be very expensive. This will occasionally limit what can be reasonably done at a given level in a class hierarchy. The Bridge pattern mitigates class sclerosis by decoupling interfaces from implementations, and putting the abstraction and implementation in separate class hierarchies. This allows the interface and implementation classes to vary independently, and the inherent substitutability of subclasses makes the structure intrinsically adaptable (and hence reusable). The Bridge in all this is the relationship between the interface and the implementation objects that together form a self-supporting system. |
A.K.A. | “Handle And Body” and “Envelope And Letter”. Those descriptive names are good-the dual-object nature of Bridge patterns is well conveyed, as is the tight coupling usually found between the programming interface and implementation objects. |
Visual FoxPro samples
Here we’ll look at three simple ways Bridge patterns can be built in Microsoft® FoxPro®: First with member properties, second we’ll do more flexible implementations using member arrays, and third using object composition within containers.
Member property bridge
One way to build a Bridge is as diagrammed below. Here an interface member property contains a reference to an implementation object.
Figure 6. Bridge pattern where an interface class member property points to an implementation class. The Bridge in this diagram is .oImp, the member property that stores a reference to an implementation object-that's physically what the arrow represents. The benefit is this: each side can be subclassed independently of the other.
In general terms, here’s how such systems are constructed in Microsoft® Visual FoxPro®. What follows is a simple illustrative class that provides WAIT WINDOW services.
XX= CREATEOBJECT( “WaitMsgServer”) XX.Execute(“This, for now, is in a WAIT WINDOW”) DEFINE CLASS WaitMsgServer AS MsgInterface FUNCTION Init( txPassed) *-- Load an interface object THIS.aImp= CREATEOBJECT(“WaitMsg”) ENDFUNC FUNCTION Execute( txPassed) *-- Pass the request along… THIS.aImp.Execute( txPassed) ENDFUNC ENDDEFINE DEFINE CLASS WaitMsg AS MsgImplementation FUNCTION Show( txPara1) WAIT WINDOW THIS.cMessage ENDFUNC ENDDEFINE DEFINE CLASS MsgInterface AS CUSTOM *-- Abstract message interface class aImp= .NULL. FUNCTION Execute( txPassed)
*-- Abstract ENDFUNC ENDDEFINE DEFINE Class MsgImplementation AS Custom *-- Abstract message implementation class cMessage= ‘’ FUNCTION Execute( tcPassed) THIS.cMessage=tcPassed THIS.Show() ENDFUNC FUNCTION Show
*-- Abstract
ENDFUNC ENDDEFINE
Sample 1. A simple Bridge using a member property to reference the implementation object.
Another example of this sort of Bridge is found in Codebook where the cBizobj (business object) class uses an object of the cDataBehavior class to implement the usual table navigation and record-processing functions. The following diagram illustrates this.
Figure 7. This Bridge pattern in Codebook 3.0 hangs on an aptly named member property. Any of the cDataBehavior subclasses may be substituted.
Member array bridge
Starting from the Member Property Bridge, it’s a short stretch to provide multiple simultaneous implementations by using multiple member properties or, as described below, member arrays.
Figure 8. A flexible BRIDGE: a selection of implementations stored in a member array.
Code sample 1 is modified here to support four different types of dialogs to extend the legacy WAIT WINDOW capability.
DEFINE CLASS WaitMsgServer AS MsgInterface FUNCTION Init *-- Load interface objects THIS.aImp[1]= CREATEOBJECT(“WaitMsg”) THIS.aImp[2]= CREATEOBJECT(“RegularMsg”) THIS.aImp[3]= CREATEOBJECT(“InfoMsg”) THIS.aImp[4]= CREATEOBJECT(“WarningMsg”) THIS.aImp[5]= CREATEOBJECT(“ErrorMsg”) *-- Supporting the legacy singular WaitMsg capability THIS.oImp= aImp[1] ENDFUNC FUNCTION Execute( txPassed, tnMessageType) THIS.aImp[tnMessageType].Execute( txPassed) ENDFUNC ENDDEFINE DEFINE CLASS WaitMsg AS MsgImplementation FUNCTION SHOW( txPara1) WAIT WINDOW THIS.cMessage ENDFUNC ENDDEFINE DEFINE CLASS RegularMsg AS MsgBoxImplementation cTitle= “My Application” ENDDEFINE DEFINE CLASS InfoMsg AS RegularMsg nIcon= 64 ENDDEFINE DEFINE CLASS WarningMsg AS InfoMsg nIcon= 48 ENDDEFINE DEFINE CLASS ErrorMsg AS WarningMsg nIcon= 16 nButtons= 5 ENDDEFINE DEFINE CLASS MsgInterface AS CUSTOM *-- Abstract message interface class DIMENSION aImp[4] aImp[1]= .NULL. aImp[2]= .NULL. aImp[3]= .NULL. aImp[4]= .NULL. *-- Virtual FUNCTION Execute( txPassed) ENDDEFINE DEFINE CLASS MsgBoxImplementation AS MsgImplementation nIcon= 0 nButtons= 0 FUNCTION Show =MessageBox( THIS.ctext, THIS.nIcon+THIS.nButtons, THIS.cTitle) ENDFUNC ENDDEFINE DEFINE Class MsgImplementation AS Custom *-- Abstract message implementation class cMessage= ‘’ FUNCTION Execute( tcPassed) THIS.cMessage=tcPassed THIS.show() ENDFUNC *-- Virtual FUNCTION Show ENDFUNC ENDDEFINE
Sample 2. Many implementations can be connected to an interface array member property.
Containership bridge
Containership implementations are similar to array member implementations. In Microsoft Visual FoxPro, containership is superbly implemented, so containership Bridges are easy to create and manage. Useful are the Controls() array, the PARENT keyword, SetAll(), and AMEMBERS(,,2), which make it possible to manage containership nesting.
The containership relationship is illustrated below, followed by an illustrative code example.
Figure 9. An interface container contains one or many implementations.
DEFINE CLASS MsgServer AS MsgInterface FUNCTION Init *-- Load an interface object with implementations. *-- Exercise for the reader: Imagine delaying *-- the AddObject calls until actually needed. THIS.AddObject( “msgWaitWindow”,”WaitMsg”) THIS.AddObject( “msgRegular”, “RegularMsg”) THIS.AddObject( “msgInfo”, “InfoMsg”) THIS.AddObject( “msgWarning”, “WarningMsg”) THIS.AddObject( “msgError”, “ErrorMsg”) ENDFUNC FUNCTION Execute( tnPassed, tcMessage) *? I don't recommend doing it quite like this --
*? This simple example assumes you know the number of the
*? implementation object. In a perfect but (less concise)
*? example, .Execute(x,y) could accept an x of type "C", as in *? <whatever_message_server>.Execute("Warning", <Message>)
*? THIS.Controls(tnPassed).Execute(tcMessage) ENDFUNC ENDDEFINE DEFINE CLASS WaitMsg AS MsgImplementation FUNCTION SHOW( txPara1) WAIT WINDOW THIS.cMessage ENDFUNC ENDDEFINE DEFINE CLASS RegularMsg AS MsgBoxImplementation cTitle= “My Application” ENDDEFINE DEFINE CLASS InfoMsg AS RegularMsg nIcon= 64 ENDDEFINE DEFINE CLASS WarningMsg AS InfoMsg nIcon= 48 ENDDEFINE DEFINE CLASS ErrorMsg AS WarningMsg nIcon= 16 nButtons= 5 ENDDEFINE DEFINE CLASS MsgInterface AS Container *-- Abstract message interface class *? Hardcoded dimension DIMENSION aImp[4] aImp[1]= .NULL. aImp[2]= .NULL. aImp[3]= .NULL. aImp[4]= .NULL. FUNCTION Execute( txPassed)
*-- Abstract method RETURN 0 ENDDEFINE DEFINE Class MsgImplementation AS Custom *-- Abstract message implementation class cMessage= '' FUNCTION Execute( tcPassed) THIS.cMessage=tcPassed THIS.Show() FUNCTION Show
*-- Abstract method RETURN 0 ENDDEFINE DEFINE CLASS MsgBoxImplementation AS MsgImplementation nIcon= 0 nButtons= 0 FUNCTION Show =MessageBox( THIS.ctext, THIS.nIcon+THIS.nButtons, THIS.cTitle) ENDFUNC ENDDEFINE
Sample 3. Multiple implementations instanciated in an interface container.
Observers define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
Problem | When one object changes, you need to update dependents. However, you feel uneasy about introducing dependencies among objects in code. |
Context | Objects are not islands; they need to cooperate together. |
Forces |
á Explicitly linking all the objects together limits reuse because of the required references which exhibit strong coupling. á Explicitly linking all the objects together makes maintenance more difficult because it increases the level of connaiscence between objects. á Explicitly linking all the objects together limits the ease extensibility of the system because the difficulty of adding new participants increases linearly with the number of participants. |
Solution | Create new relationships wherein one object (the Observer) defines and manages the dependencies between other objects (its subjects) and triggers appropriate action based on the state of those subjects. |
Resulting Context | Instead of knowing all the other subjects, a subject needs only know the Observer. This drastically reduces the overall coupling found within a system. |
Rationale |
Observer patterns work by providing a common interface and centralized dispatching for cooperative behavior. Observer objects typically query or respond to one or more of its subjects, and provide synchronization services (or initiates external synchronization services) according to the state of its subjects. Without an Observer object, the number of possible inter-object relationships grows dramatically as the number of interdependent objects in a system increases. |
Variants
The Observer pattern, useful in and of itself, is the basis for a significant number of variants. One way to segment these variants is whether the observer is implemented using a “push” or “pull” protocol.
An active (pull) observer will pull the state of its subjects to them. This is usually done within an event loop or with a timer. The Voyeur pattern (exemplified by Ken Levy’s SuperCls utility) is an example of this variant.
A passive (push) observer needs its subjects to send notification messages in order for the observer to perform its role. The Mediator pattern (page 9) is an example of this.
Visual FoxPro samples
Observers are commonplace and, if you look carefully, they can be found almost everywhere. I found one in FoxPro’s Tasmanian Traders sample application, wherein the “Behind the Scenes” form possesses a splitter control that changes the width of various form objects. The splitter control is composed of (among other things) two Commandbuttons (arrows pointing left and right) and a “splitter” Shape. These controls delegate to the control container, which then dispatches messages to various objects on the form based on the overall state of the control.
In this case the Splitter control container itself can be considered a passive observer. The CommandButton.Click() methods and the shpHandle.MouseDown method send Splitter.UpdateControls() messages. The Splitter.UpdateControls() “observes” the shpHandle.Left property and thereafter sends a message that causes external objects to be resized.
A Mediator object is a form of Observer that abstracts inter-workings of two or more objects. They are communication hubs that serve to decouple objects-objects don’t need to know about each other, they just need to know their Mediator. Mediator promotes loose coupling by keeping objects from referencing to each other explicitly, and lets you vary their interaction independently.
Look for Mediator patterns where objects are decoupled and in situations when inter-object behavior variation is present or expected. Mediators well serve situations where complex protocols must be managed, and when centralized access points are desirable.
Mediator is a behavioral pattern. When we speak of Mediator, it’s a system of at least three objects messaging in a star topology.
Figure 10. The Mediator provides a common connection point, centralized (and subclassable) behavior and behavior management, all with a common interface. As the number of colleagues increases, the number of total communication pathways is vastly reduced.
Sample mediator implementations in Visual FoxPro
The horizontal splitter control in Tazmanian Traders, which comes from the tsGen class library in the Visual FoxPro samples, contains two shapes and two scrolling command buttons. As the handle shape is moved, or the scroll buttons are clicked, messages are sent to the splitter, which then messages selected items on the form.
In Codebook, toolbar navigation buttons call a business object class (cBizObj) which mediates in a one-way direction between the form (of class cBizObjForm) and the data behavior object (of class cDataBehavior). This simplifies the programming interface - only the cBizObj class protocols need be known - and allows for the easy substitution of the data behavior implementations from the cDatabehavior class. Note that several BRIDGE patterns are evident here separating programming interfaces from implementations.
Figure 11. Hitting the Next button in Codebook. The cBizObj class mediates between the form and the desired behavior.
A decorator wrapper (I'll just call it Decorator) is an elegant OOP technique that can be handy in a wide variety of situations. In particular, the Decorator pattern is useful for extending the functionality of a class without polluting (or even needing) the original source.
Subclassing isn't always cool
But before we get to the decorator pattern, lets examine what happens when we allow a class to grow organically with inheritance. To illustrate, consider the following class interface for a frog:
DEFINE CLASS Frog AS CUSTOM FUNCTION Jump(nValue) FUNCTION Eat() ENDDEFINE
Amphibians are easily created with Visual FoxPro. Suppose that we needed to create a new sort of frog, one that can dance. We could subclass Frog as follows:
DEFINE CLASS DancingFrog AS Frog FUNCTION Dance() ENDDEFINE
Suppose we later need a singing Frog. Well, within our current hierarchy, we have several obvious options.
We could simply augment the DancingFrog with a Sing() method, perhaps renaming the class, if that's possible, to EntertainingFrog to better reflect its enhanced functionality.
We could subclass the DancingFrog, add a Sing() method to the new subclass, and call the new class, say, DancingSingingFrog.
We could insert a new Frog subclass in the hierarchy, before DancingFrog, endow it with a Sing() method, and call it, say, SingingDancingFrog.
We could make all Frogs able to sing by augmenting original Frog class.
What the heck, we could vastly simplify this rapidly exploding hierarchy by eliminating the DancingFrog class and give every Frog the Sing() and Dance() methods in a single and monolithic Frog class.
So, buffeted by the needs of this current implementation, you make your choice and you take your chances. What if you later needed a burping frog, one that belches after meals. Do we subclass again? If so, where? Do we add a Burp() method, or do we simply augment the Eat() method because problem analysis indicates that burping naturally follows from eating. Again, which hierarchical level is best for modification? And later, when you need a frog that can beg, roll-over, shake-a-leg, and stay, a new question eventually arises: "How did this Frog class become such a mess?".
At the outset, a pragmatic reuse artists would be correct in asking when, if ever, will the need for a singing, dancing, and belching frog ever arise again? Why not just augment the frog for this instance, without polluting with trivial nuance our general, simple, and reusable Frog class?
The decorator alternative
The answer may be to use a decorator. A decorator is, in essence, a class with mostly "pass-through" behavior. It "wraps" a class by reference, forwarding all messages to the reference except for the messages the wrapper is designed to intercept. Setting up a decorator takes a bit of work, but thereafter it's a snap to use. Consider the following DecoFrog class:
DEFINE CLASS DecoFrog AS CUSTOM oRealFrog= .NULL. FUNCTION INIT( oFrog) THIS.oRealFrog= oFrog FUNCTION Jump(n) THIS.oRealFrog.Jump(n) FUNCTION Eat() THIS.oRealFrog.Eat() ENDDEFINE
Sample 1. Notice the key element of decorators: They are "transparent", passing through all messages except for those that need to be intercepted. Creating an abstract decorator class (like the one above) that passes through everything is the first step. Now to augment the frog for a particular instance, we can use a simple subclass of the decorator without polluting the Frog class.
To the outside world, the DecoFrog class has the same programming interface as a Frog. But it's not a Frog, it's a lens through which we can "see" a Frog. If we need a specialized one-off Frog, like one that sings, we could do this:
DEFINE CLASS DecoSingingFrog AS FrogDecorator FUNCTION Sing() ? WAIT WINDOW "It's not easy being green..." ENDDEFINE
Similarly, we can define a dancing frog by simply subclassing the class DecoFrog as follows:
DEFINE CLASS DecoDancingFrog AS DecoFrog FUNCTION Dance() DecoFrog::Jump(+1) DecoFrog::Jump(-2) DecoFrog::Jump(+1) ENDDEFINE
Retrofitting a decorator is easy. Where before your code looked like this:
Kermit=CREATE( "Frog")
A singing frog can now be substituted at run-time like this:
Kermit=CREATE("Frog") Kermit=CREATE("DecoSingingFrog",Kermit)
or more succinctly:
Kermit=CREATE("DecoSingingFrog",CREATE("Frog"))
(Note that nesting CREATEOBJECT statements work just fine in Visual FoxPro).
Additionally, decorators can be chained, with functionality added or modified as needed! This gives you considerable pay-as-you-go flexibility. For example, to build a singing and dancing frog, do as follows:
Kermit=CREATE("Frog") Kermit=CREATE("DecoSingingFrog",Kermit) Kermit=CREATE("DecoDancingFrog",Kermit)
or, if you prefer one-line of code:
Kermit=CREATE("DecoDancingFrog", ; CREATE("DecoSingingFrog",CREATE("Frog")))
Which creates an object relationship illustrated by the following object diagram:
Figure 1. Two decorators chained together, both augmenting the object.
Well, Tada! We now have an ordinary Frog named Kermit that appears, in this instance, with the ability to sing and dance, and we didn't need to pollute the Frog class to get it. In fact, we didn't need the source to class Frog.
Decorator Benefits
Here are some benefits that come from using decorators.
Decorator downsides
As with all things, the "no free lunch" pattern applies: You cannot get the added flexibility afforded by using a decorator without some tradeoffs. Here are some of them:
Figure 2. One of the difficulties of managing a DECORATOR is maintaining its interface in synch with the objects to be decorated. Problems can be greatly alleviated by making the decorator a subclass of an abstract class, one whose sole purpose is (by definition) to define the class interface.
Figure 3. Here is how the Frog class might look, with emphasis on the evolution of its decorators to enhance otherwise normal and unentertaining frogs.
Conclusion
Decorators change the appearance of an object in a way that is fundamentally different from subclassing. Subclassing changes class internals. A decorator changes the class appearance.
Decorators are not solutions for every situation, but occasionally they are just the ticket. The next time you find yourself sub-classing for the purposes of a particular implementation, ask yourself if a decorator wouldn't better suit your situation.
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
Some selected snippets from a Pattern FAQ which is found at http://gee.cs.oswego.edu/dl/pd-FAQ/pd-FAQ.html.
What else can patterns be applied to?
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: Benefitting 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?
© 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.