Choosing an interpreter
introduction
framework
patterns
components
conclusions
references
appendix
experience
The envelope/letter idiom (originally introduced
in [Coplien] is increasingly adopted
as a standard approach to separate the definition of
a high level interface and its realization by
an implementation class.
Usually, this involves two classes,
say an abstract class A
and its implementation class AImpl.
A disadvantage of this approach is that an additional
(implementation class) is added to the class (name) space.
Another disadvantage is that refining the behavior of
a class using inheritance becomes more cumbersome.
To illustrate our approach, look at the definition
of the class kit:
class kit {
public:
kit( char* kind = "tcl" );
virtual int eval(char* cmd) { return _kit?_kit->eval(cmd):0; }
...
protected:
kit( kit* );
kit* _kit;
};
The constructor of kit indicates
as a default a Tcl interpreter which is encapsulated
by the class:
class tcl_kit : public kit {
public:
tcl_kit() : kit(0) { ... }
...
};
The constructor of kit assigns the tcl_kit
instance to its _kit variable.
In contrast, the tcl_kit initializes its
(parent) _kit variable to zero.
For the kit instance created by the user,
calls are delegated to the tcl_kit
instance.
However, the user may still inherit from kit
and selectively override its functions.
introduction
framework
patterns
components
conclusions
references
appendix
experience