Created 1/6/01 - Last Updated 1/16/01 - Jack Harich - Go Home
Definition
A pattern is a reusable set of standard roles and relationships.We are all pattern experts. We are just not yet software pattern experts. :-)
For example, we can spot a "family" when we see one, or design one to fit a story. A family has two parents and one or more children. The parents are (usually) married, have children, and the children have the parents. In this example the pattern name is "Family", the roles are "parent" and "child", and the relationships are "is married to" and "have".
Thus any pattern is defined by its standard roles and relationships. The pattern is reused by applying to a specific situation, filling those roles and establishing the relationships. An alternate definition is a pattern is a reusable solution to a design problem. However this is less exact and drifts into usage, so I prefer the first one. Getting verbose, one could say "A pattern is a set of standard roles and relationships that is designed to be a reusable solution to a recurring design problem."
A role is standard behavior that something should perform. A relationship connects two role players and allows them to collaborate. Relationships can be one way or two way.
When we say "pattern" we really mean "system pattern". A system is a collection of interacting elements, so a system pattern is how some of those elements are organized in a standard manner according to the roles and relationships of the pattern. When we say "pattern" we don't mean "the presence of recognizable repeating or ordered elements", such as in a snowflake, morse code or a stock market graph. My apologies for the potential confusion, but that's the way it is with an ambiguous language like English.
A good pattern has an easily understood standard name. This encourages a common design vocabularly. But remember the name is not the pattern, it only identifies the pattern, and so is not part of the definition of a pattern. Patterns can have alternate names.
An Alternate Definition
(If you are new to patterns, skip this section and read it later. It's a bit confusing.)
Some pattern definitions are entirely different. For example the GOF book, "Design Patterns", beats around the bush and never offers a precise definition of pattern, though they have Alexander's definition of how patterns are used. The closest it comes to a definition is patterns have four essential elements: a name, the problem the pattern solves, the solution, and the consequences, better known as pros and cons. It does say that design patterns are "descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context".
After years of studyng and using patterns, my humble opinion is this definition is a bit verbose, confusing and restrictive. It appears to be an overly academic approach, which agrees with the fact the book started as a PHD thesis, and as I recall much work was done on research grants. Let's remember the prime purpose of most academic work is to impress, not inform. After all, the motto of academics is "publish or perish". But no doubt about it, the book is a masterpiece. It's few shortcomings should be understood and ignored.
The GOF pattern definition is verbose and confusing because it mixes "how to use something" with the definition of what it is, and is thus too long to memorize or understand quickly. This is a heavy amount of mental baggage to add to each pattern that one must learn. The novice doesn't notice this problem, and is lost at sea.... By contrast, consider a bolt. It can be defined as a usually strong, long, heavy object with a shaped head for tightening or loosening, an optional smooth shaft in the middle, and a threaded shaft on the end opposite the head to engage whatever the bolt is fastened to. Few would dream of adding to this descriptive definition what problems bolts can solve and their pros and cons, because this would take thousands of words and need frequent updating. The point I wish to make here is a definition should say what something is, not how to use it.
The GOF pattern definition is restrictive because by including the problems it solves with the definition, it implies those are the only problems it solves. Let's return to the bolt definition. If use was part of the definition, it would call them fasteners. But because of their weight, I have used bolts as paperweights in the wind on a three story building that had the windows open all day. Power companies use them as footholds on metal phone poles. Fishermen use them as sinkers, etc, etc. Instead of combining use with definition, authors should think broader and list prime or sample uses.
I would agree with the GOF definition of pattern if it was the definition of a minimum pattern catalogue entry, where the purpose of a catalogue entry was to cover sufficient information needed to initially understand and use a pattern.
Visualization
The roles and relationships of patterns are easily portrayed in a diagram. For example the Family Pattern would look like the diagram on the right, also known as a model. The chief advantage of a visual model is quicker communication. Other advantages are conciseness, ease of editing, ease of reproduction, and ease of standardization. Small wonder that models are often far more useful than text to describe patterns.
A pattern model shows a typical application of the pattern. For example not all families have two daughters and one son.
Note the two way links, indicated by an arrow on each end. This means the parents can initiate communication with the children, and ditto for the children. Two Way Link is a pattern itself.
Note how the richness of a visual display lets us add more information without confusion. The added information is Mother, Father, Son and Daughter.
The moral of the story is patterns are so information rich you must think visually to best think in terms of patterns. This ability is easily cultivated by drawing lots of patterns, studying many patterns, and modeling before coding. Optimum pattern use is inherently visual, which I realize is a controversial stance.
A problem is most developers are code centric. While they may think spatially when visualizing the solution of a problem as code to be written, they are not visualizing or drawing a cohesive model. This creates the following problems with using patterns:
- Patterns are best visually modeled, so it's harder for code centric developers to exploit patterns.
- It's harder for code centric developers to communicate their designs or implementations.
- It's harder for an organization to encourage the use of patterns.
Here's a tip. You can walk around and spot visual types and code centric types with ease. The visual types are the ones with plenty of models on their walls or desk. When they're coding they are looking at or thinking of a visual model. They're also the ones more like to be using multiple terminals, so they can have a modeling tool on one and a coding tool on the other. This allows them to see the model while implementing it at all times. Without the second monitor there's a strong tendency to not keep the model up to date, not model first and code second, and in general to be way too code centric. It's a little like how difficult it would be to drive if the windshield view and the dashboard were not visible at the same time.
Further Visualization Examples
As we mentioned before, we are all pattern experts. The problem is we are just not yet software pattern experts. To resolve that problem, at this point it would be helpful to show a few patterns you are already familiar with. Studying these will allow you to quickly absorb the abstraction of what a pattern really is. Let me repeat that. Study these and try to deeply understand what the concept of a pattern really means to you. Jump in and swim around in your mind a little, until you reach the depths of deep understanding.
Examine the Bridge Pattern model. Note the five standard roles. Note the standard relationships implied by the model arrangement. The Travelway is held up by the Span Supporting Structure, which rests on two Supports. The Travelway and Span Supporting Structure go over an Obstruction.
In this pattern the main purpose is not obvious if you've never seen the pattern before. This is why it's useful to state a pattern's purpose, or what problem it solves, which are the same thing. The Bridge Pattern solves the problem of how to travel over an obstruction.
Patterns can have variations. For example in a suspension bridge the Span Supporting Structure would be mostly above the Travelway. In a long bridge there can be more than two Supports. When an expressway crosses an obstruction by using a bridge, it might have two Travelways, either one above the other, or side by side. If the ground at the ends of the Span Supporting Structure is at the right height and made of rock, there might be no Supports at all. So when using patterns, immediately think in a divergent manner to generate many options, and then in a convergent manner to select the best one.
Next take a peek at the Country Pattern. The model implies that a country is a Union of Seperate Territories with a Capitol. This futher implies a country solves the problem of how best to federate a group of territoties, in a reusable manner. It's so reusable that all countries follow this pattern exactly. All countries have one Capitol and one or more Territories.
We use a little UML to show the relationships, which are all two way links.
(A) To keep the model simple, several things are not shown. For example most countries further subdivide their territories, such as the US divides states into counties. Another aspect not shown is the Capitol is located in a Territory.
What we are doing here is known as Layered Presentation. The first layer is what's shown in the model. This is minimal for easy digestion. The second layer is the further information in the text acompanying the model. For the Country Pattern the second layer is paragraph (A). An alternative would be to show a second more elaborate model with the information in paragraph (A). The reader studies the first layer, then the second layer, then the third one, etc. Each layer builds on the ones before.
A pattern is a reusable set of standard roles and relationships.Stop and draw a few patterns with pencil and paper. Write down the definition of a pattern from memory. You'll notice that at first modeling patterns is hard, because we don't think in terms of pattern models. But with perhaps 15 minutes practice you will notice that suddenly modeling patterns such as Bus Route, Kitchen, City Water Supply System, Company Organization, Telephone and Solar System become much easier. If you want more suggestions, open a dictionary at random or look around. Scribble, scribble, ponder, scribble....Boom!!! Congratulation! You are now a pattern modeler. :-)
A Typical Software Pattern
We now present a typical software pattern so the rest of this document makes sense. We deliberately keep this short and simple, to err on the side of easy comprehension rather than completeness. We also pick a simple pattern.
Description - Consider the Singleton Pattern, shown in the diagram. The roles are Single Instance and Client. The relationship is the Client(s) "has a" Single Instance. There needs to be a way for a client to get the reference, which can be done many ways.
The roles imply the use for this pattern. Use it when you want only a single instance. The relationships imply that each client has the same instance. 'Nuf said.
Example - For example your design might require a Singleton for a database connection pool. The following Java class would do the trick. Note the static method for clients to get their reference.
public class ConnectionPool { protected static ConnectionPool singleton = new ConnectionPool();
protected ArrayList pool = new ArrayList(); public static ConnectionPool getInstance() { return singleton; } public Connection acquireConnection() { if (pool.isEmpty()) {
return createConnection();
} else {
return (Connection)pool.remove(pool.size() - 1); } } public void releaseConnection(Connection conn) { pool.add(conn); }
protected Connection createConnection() {
// Do some work here....
}
protected ConnectionPool() { }
}Note how the getInstance() method is static. This makes presenting a single instance easy. But is also leaves the door open to future designs where different instances might be returned. Thus we recommend not using methods names like getSingleton() because they limit the designer's flexibility. Good code is self-documenting.
Note also that the final client may not be the one that calls getInstance(). This can be done by a mediator. For example you might have a class named NodeContext with the method getConnectionPool(). This method would not be static. It would call ConnectionPool.getInstance() and return a ConnectionPool.
Finally, note the protected constructor. This prevents clients from circumventing getInstance() by creating a new instance themselves. A do nothing non-public constructor like this is a popular trick.
Pattern Selection
Probably the hardest part of using patterns is selecting the best pattern. We offer no astounding answers here. Pattern selection is just like generating solution options and selecting the best one, which is common to all problem solving. The best we can do is offer a common sense approach to learning pattern selection:
1. The first thing to do is deeply understand what patterns really are. For that we recommend study, practice and creation of some of your own patterns. This is also known as the "Three I's" - Immersion, Imitation and Innovation, a powerful reusable road to progressive mastery. Set yourself something like these goals, where you are able to:
A. Explain what patterns are to anyone (even non-developers).
B. List and define 20 patterns in detail.
C. Analyze any model for proper use of patterns.
D. Point to successful use of at least 5 of your own patterns.
2. Next one must learn (memorize and understand) lots of patterns and add them to your arsenal of known patterns. This is not as hard as it seems at first. There are only a few dozen basic patterns. The rest are variations. Memorize the basics and some of the variations, and use reference material for the rest. Be especially sure to focus on the patterns most used in your domains. For example I'd estimate I know fifty patterns, and can lookup 100 more I'm already familiar with.
3. Develop an intuitive sense of when a pattern solves a problem well. This will appear with practice, as you see how your pattern selections make reuse, maintenance, massive design changes, and system understanding easier in some cases, and harder in others. There is no substitute for practice, practice, practice. This ability will allow you to mentally consider pattern after pattern after pattern, and select the best one in seconds. Eventually most of this happens subconsciously.
4. Now the magic happens. When modeling decisions arise you will now naturally respond in terms of patterns plus "custom clumps", whereas before it was all custom roles and relationships. Your highly engineered models will be over 50% patterns. Some may hit 100%. When that starts happening, you know you're there.
A custom clump is a local group of roles and relationships that are not part of a pattern. Since they are not standards derived from a pattern they are custom. Whenever you see custom clumps what you're really seeing is a lost potential reuse case. Patterns are a form of reuse.
A Few Pitfalls to Avoid
1. Don't assume that a pattern is always better than no pattern. Only use a pattern if it solves a problem well. If a pattern doesn't solve a problem well, try other patterns, try a custom clump, or change the overall design. Pattern beginners will tend to use lots of patterns arbitrarily, but the resultant system is immediately awkward to the trained eye, and horrendous to whoever comes after you.
2. Don't go wild with custom patterns. The thrill of invention is irresistible to some. Don't let it infect you.
3. Don't blindly try to sprinkle as many patterns in your models as you can.
4. Don't assume your fellow developers will learn patterns as fast as you. People learn and work at different speeds. Fortunately we are all unique.
5. Don't assume patterns will solve lots of your problems. They are not a silver bullet, just another tool in your engineer's toolbox. They will not automatically speed up development by even 10%. But if you learn and add such goodies to you toolbox every month or so, you will soon double your productivity. This is because of the compounding nature of most productivity abstractions, such as process, modeling, patterns, use cases, declarative knowledge, xml, reusable components, frameworks, automatic test suites, defensive programming, etc.
A Few Valuable Suggestions
1. As you are learning patterns, accumulate a list of your favorites.
2. As your organization invents custom patterns, publish them.
3. When refactoring you can often turn a custom clump into a pattern.
4. Improve your definition of particular patterns as you understand them deeper, or as new aspects appear due to novel use.
5. As you design, try to express youself with 100% patterns. Try to get every class to fill a reusable standard role. This usually can't be done, but just trying will automatically improve the design, unless you "force a pattern" that really should not be used.
6. Consider having someone in your organization evangelize patterns.
7. Often the use of a certain pattern will make or break an entire design. Press hard to find the right key pattern. For example the portability model of Java itself falls into place with the Fascade Pattern, with the JVM as a fascade between the host operating system and the application. In retrospect this is Java's most valuable feature. Imagine that - One simple pattern has changed the course of software history....
8. Patterns have variations. In fact a pattern definition is usually very abstract. It's up to you to apply the abstraction to your problem correctly. No automatic rules will work every time. Think in a fluid manner.
9. The hardest step in OOAD is translating requirements into classes. Patterns can help tremendously here. The more you are familiar with the better, up to the point of diminishing returns. With patterns the designer is not meandering around in the dark, because they have been there before.
Types of Patterns
(to be continued)
Pattern Summaries
Here are a few very handy "pattern summaries".