Note that the GangOfFour book is chock full of useful general advice and insight in the first few chapters where they talk about using delegation, and preferring composition over inheritance, and encapsulating variation. Those are common themes underlying many of the pattern solutions; but the GoF didn't consider them patterns in that general form. It wasn't until we saw a specific application of one or more of those principles in practice to solve a concrete problem that the form of applying those principles in that context manifests itself as a "pattern."
Each pattern in the GoF book is yet another data-point showing how to apply much the same principles and heuristics in each of about two dozen different situations. Each of those context-specific problem/solution pairs is another instance of how and why the same general "rules of thumb" were applied to a specific scenario. Each pattern gives us more understanding into how to practically apply and adapt those deeper, more fundamental and more general guidelines to the concrete situations we encounter.
As each pattern exposes yet another concrete manifestation of how to balance many of the same forces according to many of the same broad & general ideas, it teaches us the about the fundamental nature of solving or approaching an infinite number of problems in the same overall domain and its competing concerns.
It is through the repeated examples of concrete solutions to concrete problems and the description of how they trade-off forces that patterns teach us the recurring themes about how to trade-off those forces in general. Those incredibly general rules of thumb are incredibly useful and incredibly insightful.
But the patterns aren't the general principles themselves - they are the results of applying them in practice to specific real world problems. The patterns teach us more about the deep workings of those general themes/principles than many of us could understand from seeing only the general descriptions of them without the examples of their application to specific problems and contexts via patterns.
Are you saying that something that is in the form of a pattern but has very wide applicability is not a pattern?
The short answer is that it's not a pattern if you can't nail down any even remotely concrete problem and context to go with it. That doesn't mean its no good, or any less good, just that its not a pattern.
The long answer is ... uh ... long (about another 100 lines or so :-)! If something is so widely applicable as to be useful for almost any kind of (O-O in this case) problem - then I would almost certainly say it's not a pattern. Being useful and recurring doesn't mean that they are a solution to a specific problem in a context.
If it's so general as to be applicable to most any problem in the domain, then it's unlikely to be able to show me the specific "thing" to use (and the specific process for how to create that thing) for a specific problem I am trying to solve. For example, the concept of polymorphism is not an O-O design/coding pattern IMHO. It's the specific way it is used to overcome a problem in a certain context that is a candidate for pattern-hood. Most of the other "GRASP" items fall into this category.
Consider things like "prefer composition over inheritance" or "add another level of indirection by adding another object" or "encapsulate the thing that varies." These are abstract solutions in search of a specific problem to apply them to. They are enormously general and widely applicable. And for that reason they don't tell me how I can go about the details of using them for my specific problem.
MediatorPattern tells me one way of applying those things to a concrete problem. StrategyPattern applies all those same things to a different concrete problem. AdapterPattern does the same for yet another problem. And so on with may of other GangOfFour patterns. And the result of using all those things gives me a different kind of concretely visible solution for each different problem (the pictures and diagrams and collaborations are noticeably different because they are tailored to a more concrete context).
If I were staring the specific problem for "visitor" or "adapter" or "mediator" in the face and didn't know the solution, and you said to me "prefer composition over inheritance" and "add another level of indirection by adding another object" and "encapsulate the thing that varies" then you have given me some very insightful yet abstract, and quite possibly impenetrable, hints. But you most definitely have not shown me the solution to my problem.
I have to figure out where to add the extra object, which things it needs to indirect between, which parts of it I need to vary, and which parts to consider using inheritance so that I can see if I could replace it with composition. I have to figure out every single one of those things on my own, before I can have a workable skeleton of a solution.
But that skeleton is going to look markedly different for each of Adapter and Visitor and Mediator. Their "pictures" won't look similar enough for me to easily infer any one of them from the other, nor all three of them from a more abstract statement with an even more abstract picture (or it may even be too abstract for a picture, requiring a specific example in order to illustrate it).
The problem is that generality is the enemy of specificity, and vice versa. The more general you get, the more widely applicable and powerful; and the more distant it becomes from what's recognizable in the real world. The more specific it is, the more details you can see and recognize and understand how it works and can be used in certain conditions; and the less applicable it becomes once you do that.
Recurring "solutions" that are so widely applicable as to have no particular problem and context it is limited to are very useful and powerful things. But they are not patterns. A lot of people don't get this when they first learn patterns. They think all that's needed is a recurring solution and they can skip the problem and forces and context.
But this misses one of the more fundamental and important aspects of patterns. They are not just recurring solutions. They are well documented contextual-mappings from a recurring problem to its recurring solution!
Understanding the relationships between the problem and the solution (and the context in which they occur) is fundamental to understanding the forces of the problem, and why and how that solution resolves that problem. When you remove the problem/context and make it so broad as to be practically universal for the whole domain, you lose the connection between the solution and a specific problem.
This connection comprises one of the most valuable and most reusable parts of the pattern, which is not the raw solution itself, but the knowledge of how and when and where and why to apply it and adapt it to your needs! If all you've got is a solution, you have to figure out for yourself how and when and where to apply it for a given problem. A pattern is supposed to explain all of that for you. (A pattern language does this for a whole architecture, one problem/pattern at a time.)
A pattern is really a balance between abstractness and concreteness, between generality and specificity, and between theory and practice. The general abstract stuff looks like pure theory, and the specific concrete stuff is what we see in practice. A good pattern shows the connection between them, and how to get from each to the other.
When you lose that balance, by giving only a general solution with no specific problem, you lose that crucial link to understanding the relationships between the specific solution and the more general underpinnings of how to resolve forces in the entire domain.
A pattern has to abstract the solution and context just enough so I can still recognize it as something that occurs in practice. And it has to show enough insight and understanding of a general theory for how to resolve forces while still letting me see what the shape of that resolution looks like in practice for a specific problem and context.
A general problem with no concrete solution is still a problem. A general solution with no concrete problem doesn't help me until I see a specific problem and context to which it applies. But when I have all three recurring together, a specific problem and context and a generalized solution for it, then I have a pattern!
-- BradAppleton (posted to the patterns-discussion mailing list on May 6, 1999) [later wikified]
When I encountered Principles and examined them, I found them to be Forces. And more than that, usually free personal choices. Which means, they aren't patterns, as you say. Patterns discuss structural relationships, which a simple Principle doesn't. "Prefer this over that" is a force, not a resulting spot. -- AlistairCockburn
I agree with Alistair. Principles are usually forces. They typically are not supposed to be violated at all. I should mention that I didn't create this particular page. Someone else saw my posting to the mailing list and put it here under this particular title. My posting wasn't referring exclusively to principles, but to all sorts of other things of a very general nature that are often mistaken for patterns. They might be very general guidelines or rules of thumb as well as principles.
Pattern writers obviously need to do some amount of abstracting when they describe the context, problem, forces, and solution. It's tempting to abstract too far, to the point where all that remains is this immensely general purpose solution. But when we do that, we lose the concrete cognitive connection between that particular solution and the specific problem it solved within its context.
A pattern is not just the solution. The solution isn't even the most important part of the pattern; too many people miss that point. They become fixated on the solution, or upon thinking that the most valuable piece of advice must be a pattern or appear in pattern form. Important things like "favor object composition over class inheritance" aren't patterns; and they are no less important because of that.
The most useful information in a pattern isn't the solution itself so much as it is the experience and insight that went into realizing how and why it solves that problem in that context. The most valuable part is what explains the fitness of use and usefulness of fit between the problem and the solution in the given context (and how that relates to the more general issues we all face in that problem domain).
It is here that the pattern conveys more than just a cookbook solution; it conveys wisdom and experience about the solution. As a result, it actually teaches us more about the problem domain in general (and not just the solution in particular). It does this using a concrete problem and context to crystallize the forces and their resolution. This allows the pattern to then reveal the more general insight behind the forces of the entire domain, and the hard won wisdom for how to achieve balance among them. -- BradAppleton
People have an amazing degree of difficulty with form. They know about all kinds of content, but they don't know which form is best suited for which content. And in general, they are ignorant of the power of form, and the various kinds of forms. The unfortunate author of whom Brad speaks would do well to understand the patterns form -- it might save the community from more misguided books. -- JoshuaKerievsky
In the aforementioned author's defense, I believe he really is trying. He submitted to PLOP last year, and again this year; and his work really has improved (even if it's not yet where I would like it to be ;-) He learned a lot about form at PLOP last year, and why it is important. Maybe this year he will learn even more. If any one reading this page will be attending PLOP'99 and thinks they understand what this page is trying to say, then perhaps we can all make an effort to help this author and others advance their understanding.