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
HookClasses. The reasons fore this are:
- An instance of a TemplateClass can manage a number of instances of a HookClasses
- A HookMethod itself might be implemented by using another HookMethod in a HookClass. So the HookMethod is also a TemplateMethod in relation to that other HookMethod.
And, after some more in detail discussion, Pree manages to map this construction principle to quite a number of
GangOfFour design patterns. E.g. in the
InterpreterPattern the Abstract
Expression is a
HookClass, the Interpret() method is a
HookMethod and the Subject class is a
TemplateClass.
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... :-)
--
ThomasWeidenfeller
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