Chap.8: ADDING NEW PATTERNS TO THE LIBRARYInternally, the library provides plenty of examples of how you can derive a new pattern from the existing ones. For example, Aggregate and Composite are derived from Collection; Array, PtrArray, and Flyweight are derived from ArrayContainer; and internally FSM uses five ArrayContainers. Each pattern may require a different coding technique, but if you want it to fit into the framework of this library, and especially if you plan to use the Template Manager, we suggest that you follow the format of the existing *.h files, paying attention to the following details: (a) Enclose each file with #ifndef statements so that multiple includes of the same file do not cause compilation errors. For example: #ifndef AGGREGATE_USED
.... all code ....
#endif // AGGREGATE_USED
#define AGGREGATE_USED
(b) Include patterns which will be used as a part of your new pattern. For example: #include <collecti.h>
#include <arraycon.h>
(c) In the comment part, explain the parameters your new pattern/template is using, and also what classes must be inherited by the application. For example: // ---------- aggregat.h --------------------
// pattern Aggregate<P,C,i>
// where P is the parent class (for example Department),
// C is the child class (for example Employee)
// i is an integer index, usually 0
// --------------------------------------------------
// Example:
// Class Employee : public AggregateChild<Department,Employee,0> {
// ...
//};
// Class Department : public AggregateParent<Department,Employee,0> {
// ...
//};
// --------------------------------------------------
(d) Replace long templates by shorter symbols - it will make the code more readable. For example: #define pType AggregateParent<P,C,i>
#define cType AggregateChild<P,C,i>
#define iType AggregateIterator<P,C,i>
#define oType Aggregate<P,C,i>
#define pTypeC CollectionParent<P,C,i>
#define cTypeC CollectionChild<P,C,i>
#define iTypeC CollectionIterator<P,C,i>
#define oTypeC Collection<P,C,i>
(e) Code the class definition and the implementation of the template methods in a single file, including the part which (if this was not a template) would be in the *.cpp file: // part equivalent to *.h file
class XYZ {
...
void prt();
};
// part equivalent to *.cpp file
void XYZ::prt(){
...
}
...
(f) Provide hooks for the Template Manager. To understand how this works, consider the following. If your application declares pattern Aggregate<Department,Employee,0> myAggr; class Department is given No.1, and class Employee is given No.2. As a result, the statement class Department : Pattern(Department) {
... whatever
will be translated into class Department :
AggregateInherit1(myAggr,Department,Employee,0){
AggregateMember1(myAggr,Department,Employee,0)
... whatever
This permits you to arrange that the Template Manager transparently implements inheritance, but can also add members or functions to the class. For example, the setup for pattern Aggregate which is based on class Collection looks like this: #ifdef TEMPLATE_MANAGER
// Include sections - needed only when the Template Manager is used
#define AggregateInherit1(id,par,chi,i) \
public AggregateParent<par,chi,i>
#define AggregateMember1(id,par,chi,i)
#define AggregateInherit2(id,par,chi,i) \
public AggregateChild<par,chi,i>
#define AggregateMember2(id,par,chi,i)
// --------------------------------------------------
#endif // TEMPLATE_MANAGER
(g) Cancel the shorthand for your classes; otherwise, there could be a conflict with other patterns: #undef pType
#undef cType
#undef iType
#undef oType
#undef pTypeC
#undef cTypeC
#undef iTypeC
#undef oTypeC
(h) Write a test program for your new class. Test it both with and without the Template Manager, place the two copies (there should be only minor differences due to the style of using the patterns) in directories MTEST and TTEST, and the correct result in the directory OUT. |