I am a little bit reluctant to write the following, because they are definitely not my ideas. But, on the other hand, it popped up in some discussion, and I am not aware of an English reference for the information. So here is a short summary of the ConstructionPrincipleForDesignPatterns as described by WolfgangPree in KomponentenbasierteSoftwareentwicklungMitFrameworks.
WolfgangPree starts his idea with a look at the TemplateMethod and HookMethod as it e.g. can be found in the GangOfFour TemplateMethodPattern (Pree discovered that a lot of the GOF patterns are just varioations of the TemplateMethodPattern when it comes to implementation).
He then identifies a class which contains a TemplateMethod as a TemplateClass, and a class which contains a HookMethod as a HookClass (sounds obvious, doesn't it?). Now, in the simplest variant, TemplateClass and HookClass are identical (as e.g. in the example in HookMethod): TemplateMethod and HookMethod are located in the same class, and the HookMethod can only be changed by deriving a class.
In general, there is, however, no need that TemplateClass and HookClass are the same. It is "only" an implementation detail. Instead of having the HookMethod implemented in the same class, a TemplateClass could have a uses-A relation to an (abstract) HookClass, allowing the TemplateMethod in the TemplateClass to invoke the HookMethod in the HookClass.
Also, an instance of a TemplateClass can manage a number of instances of HookClasses (with whatever feature the programming language provides, e.g. pointer, list, vector,...).
Example separate template and HookClasses:
abstract class hookClass { double hookMethod(double arg); } class templateClass { templateClass(hookClass h) { hook = h; }; templateMethod(double arg) { : hook.hookMethod(arg) : } hookClass hook; }WolfgangPree further abstracts, that a TemplateClass might e.g. be constructed by deriving from an (abstract) HookClass, while the opposite, however, (HookClass derived from TemplateClass) doesn't make much sense.
Deriving a HookClass from a TemplateClass doesn't make sense, because the TemplateClass is more concrete than the HookClass (For example: The TemplateClass contains the body of an algorithm implementation, while the HookClass only contains a "detail" but not a refinement of the algorithm):
Example TemplateClasse? derived from HookClass:
abstract class hookClass { // Hook Method double calculate(double arg); } class templateClass extends hookClass { // Template Method double algorithm(double arg1, double arg2) { : x = calculate(arg1); y = calculate(arg2); : } // Default implementation of hook method double calculate(double arg) { : } } class derivedAlgorithm extends templateClass { // Change implementation of hook method double calculate(double arg) { : } }Based on this ingredients he then demonstrates that one can build chains/trees/graphs of instance of TemplateClasses? and HookClasse?s. The reasons fore this are:
But the Interpret() method is both a HookMethod and a TemplateMethod, because it usually calls Interpret() on the nodes children. And it is very common, even usual, for a HookClass to be derived from a TemplateClass. This is your typical concrete subclass derived from an abstract base class. Am I missing something?
I too feel like I'm missing something. Yes, the GangOfFour structures are composed of simpler OO bits and pieces, and yes you can filiate the structures if you like - the structures are extremely simple so this comes as no surprise at all. The value GoF and their successors are adding with patterns is not a taxonomy of common OO structures but a taxonomy of common OO problems+solutions. Filiating the solutions doesn't seem to help their application in any way unless maybe it could be used to attack the PatternOfBabel. Can it? -- PeterMerel
The conclusion I draw from the ConstructionPrincipleForDesignPatterns is, that the semantic of a pattern makes up its value, not its implementation. Different patterns might have exactly the same implementation, as well as there are multiple implementations for the same pattern (which we all already know from daily work, don't we?).
What bothers me is, if I have captured the semantic of a problem (whatever that is), can the ConstructionPrincipleForDesignPatterns be used to construct an implementation which fulfills all constraints/requirements of the problem?
Regarding the PatternOfBabel I have the impression that reverse engineering a pattern according to ConstructionPrincipleForDesignPatterns might allow insight into a pattern and allows comparisson of patterns. If someone then will also manage to come up with a catalog allowing to classify an individual usage of template and hook classes/methods, then maybe patterns are fully comparable.... See PatternLanguageTaxonomy and SoftwareEtymology
Yes, sometimes I have these strange dreams... :-)
A very interesting notion, Thomas, that different patterns might lead to the same implementation!
WardCunningham and KentBeck teach us to "listen to what Smalltalk is telling us". I take them to mean that by being sensitive to the shape of the code and of the objects, we can begin to feel that one arrangement of objects is better than another. Then we move the code in that direction.
When we do this, often we wind up with objects quite different from those we imagined when we started out - yet they are invariably better. (If only because if they aren't, we revert. :) )
I wonder, then, whether two patterns might at first direct us to produce implementations that were quite different, but the forces of refactoring bring them together.
I, too, have strange dreams ... but perhaps those are best left to another web. --RonJeffries