//
Purpose.  Template Method            // Discussion.  On the left, we're
                                        //
starting with 2 sorts that are very
#include <iostream.h>                   // similar.  If we could "customize" a
#include
<stdlib.h>                     //
single sort implementation, we could
#include <time.h>                       // enjoy reuse.  "Template Method de-
                                        //
fines an algorithm in terms of ab-
class SortUp {  ///// Shell sort /////  // stract operations that subclasses
public:                                 // override
to provide concrete beha-
   void
doIt( int v[], int n ) {        //
vior."  Here, doIt() is the
algo-
      for (int g = n/2; g
> 0; g /= 2)  // rithm, and
needSwap() is the ab-
         for
(int i = g; i < n; i++)    // stract
operation.
            for (int j =
i-g; j >= 0;
                              j -= g)   class Sort {  //////
Shell sort //////
               if
(v[j] > v[j+g])       public:
                  doSwap(v[j],v[j+g]);     void doIt( int v[], int n ) {
   }                                          for (int g = n/2; g >
0; g /= 2)
private:                                         for (int i = g; i < n;
i++)
   void doSwap(int&
a,int& b) {                     for
(int j = i-g; j >= 0;
      int
t = a; a = b; b = t; }                                      j -= g)
};                                                    
if (needSwap(v[j],
                                                                   
v[j+g]))
class SortDown {                                          doSwap(v[j],
public:                                                         
v[j+g]);
   void doIt( int
v[], int n ) {           }
      for (int g = n/2; g > 0; g /= 2)  private:
         for (int i = g; i < n; i++)       virtual int needSwap(int,int) = 0;
            for (int j = i-g; j >= 0;      void doSwap(int& a,int& b)
{
                              j
-= g)         int t = a; a = b; b = t;
}
               if (v[j] <
v[j+g])       };
                  doSwap(v[j],v[j+g]);
   }                                    class SortUp : public Sort
{
private:                                   int needSwap(int a, int b)
{
   void doSwap(int&
a,int& b) {               return (a
> b); }
      int t = a; a = b;
b = t; }        };
};                                      class
SortDown : public Sort {
                                           int needSwap(int a, int
b) {
void main( void )                             return (a < b); }
{                                       };
   const int NUM = 10;
   int      
array[NUM];                void
main( void )
   time_t    t;                         {
  
srand((unsigned) time(&t));             const int NUM = 10;
   for (int i=0; i < NUM; i++) {           int      
array[NUM];
      array[i] =
rand() % 10 + 1;          time_t    t;
      cout << array[i] << ' '; }           srand((unsigned)
time(&t));
   cout <<
endl;                           for (int
i=0; i < NUM; i++) {
                                              array[i] = rand() % 10 + 1;
   SortUp  upObj;                             cout <<
array[i] << ' '; }
  
upObj.doIt( array, NUM );              
cout << endl;
   for
(int u=0; u < NUM; u++)
     
cout << array[u] << ' ';             SortUp 
upObj;
   cout <<
endl;                          
upObj.doIt( array, NUM );
                                           for (int u=0; u <
NUM; u++)
   SortDown  downObj;                         cout << array[u] << ' ';
   downObj.doIt( array, NUM );             cout << endl;
   for (int d=0; d < NUM; d++)
      cout << array[d] << '
';             SortDown  downObj;
   cout << endl;                           downObj.doIt( array, NUM );
}                                          for
(int d=0; d < NUM; d++)
                                              cout <<
array[d] << ' ';
// 3 10 5 5 5 4 2 1 5 9                    cout << endl;
// 1 2 3 4 5 5 5 5 9
10                 }
// 10 9 5 5 5
5 4 3 2 1
                                        // 1 6 6 2 10 9 4 10 6
4
                                        // 1 2 4 4 6 6
6 9 10 10
                                        // 10 10 9 6 6 6 4 4 2
1
// Purpose.  No
reuse
#include <iostream>
using namespace std;
class
One {
   void a() { cout <<
"a  "; }
   void b() { cout << "b  "; }
   void c() { cout << "c  "; }
   void d()
{ cout << "d  "; }
   void e() { cout << "e  "; }
public:
   void execute() { a();  b(); 
c();  d();  e(); }
};
class Two {
   void a() 
{ cout << "a  ";
}
   void _2() { cout <<
"2  "; }
   void c() 
{ cout << "c  ";
}
   void _4() { cout <<
"4  "; }
   void e() 
{ cout << "e  ";
}
public:
   void execute() {
a();  _2();  c();  _4();  e(); }
};
void main( void )
{
   One first;
   first.execute();
   cout << '\n';
   Two second;
   second.execute();
  
cout << '\n';
}
// a  b  c  d 
e
// a  2  c 
4  e
//
Purpose.  Template Method design
pattern
// 1. Standardize the skeleton of an algorithm in a base
class "template method"
// 2. Steps requiring peculiar
implementations are "placeholders" in base class
// 3. Derived
classes implement placeholder methods
#include
<iostream>
using namespace std;
class Base {
   void a() { cout << "a  "; }
   void c() { cout << "c  "; }
   void e()
{ cout << "e  "; }
   // 2. Steps requiring peculiar
implementations are "placeholders" in base class
   virtual void ph1() = 0;
   virtual void ph2() = 0;
public:
   // 1. Standardize the skeleton of an
algorithm in a base class "template method"
   void execute() {  a();  ph1();  c(); 
ph2();  e(); }
};
class
One : public Base {
   // 3.
Derived classes implement placeholder methods
   /*virtual*/ void ph1() { cout << "b  "; }
   /*virtual*/ void ph2() { cout << "d  "; }
};
class Two :
public Base {
   /*virtual*/ void
ph1() { cout << "2  ";
}
   /*virtual*/ void ph2() { cout
<< "4  "; }
};
void
main( void ) {
   Base* array[] = {
&One(), &Two() };
   for
(int i=0; i < 2; i++) {
     
array[i]->execute();
     
cout << '\n';
} 
}
// a  b  c 
d  e
// a  2 
c  4  e
// Purpose. Template Method design
pattern
// 1. Standardize the skeleton of an algorithm in a base
class "template method"
// 2. Steps requiring peculiar
implementations are "placeholders" in base class
// 3. Derived
classes implement placeholder methods
#include
<iostream>
#include <string>
using namespace std;
class
StandardAlgorithm {
   // 3. Steps
requiring peculiar implementations are "placeholders" in base
class
   virtual string preprocess(
char* ) = 0;
   virtual bool   validate( char )    = 0;
public:
  
// 1. Standardize the skeleton of algorithm in base class "template
method"
   string process(
char* in ) {
      string str =
preprocess( in );
      for (int
i=0; i < str.size(); i++)
        
if ( ! validate( str[i] )) return "not valid";
      return str;
}  };
class Alphabetic : public
StandardAlgorithm {
   /*virtual*/
string preprocess( char* in ) {
     
string s( in );
      for
(int i=0; i < s.size(); i++)
        
if (s[i] >= 'A' && s[i] <= 'Z' || s[i] == ' ') /* empty */
;
         else if (s[i] >= 'a'
&& s[i] <= 'z')          
s[i] = s[i] - 32;
        
else                                           s[i] = '_';
      return s;
   }
  
/*virtual*/ bool validate( char ch ) {
      if (ch >= 'A' && ch <= 'Z' || ch == ' ') return
true;
      else return
false;
}  };
class
Numeric : public StandardAlgorithm {
  
/*virtual*/ string preprocess( char* in ) { return in; }
   /*virtual*/ bool validate( char ch )
{
      if (ch >= '0' &&
ch <= '9') return true;
     
else return false;
} 
};
void main( void ) {
   StandardAlgorithm* types[] = { &Alphabetic(), &Numeric()
};
   char buf[20];
   while (true) {
      cout << "Input: ";
      cin.getline( buf, 20 );
      if ( ! strcmp( buf, "quit" ))
break;
      for (int i=0; i <
2; i++)
         cout <<
"   " <<
types[i]->process( buf ) << '\n';
}  }
// Input: Hello World
//    HELLO WORLD
//    not valid
// Input: 12345
//    not valid
//    12345
// Input: 4.2e3
//    not valid
//    not valid
// Input: quit
//
Purpose. Template Method design pattern
// 1. Standardize the
skeleton of an algorithm in a base class "template" method
// 2.
Common implementations of individual steps are defined in the base class
//
3. Steps requiring peculiar implementations are "placeholders" in
base class
// 4. Derived classes can override placeholder methods
//
5. Derived classes can override implemented methods
// 6. Derived classes
can override and "call back to" base class methods
#include
<iostream>
using namespace std;
class A {
public:
   // 1. Standardize the skeleton of an
algorithm in a "template" method
   void findSolution() {
     
stepOne();
     
stepTwo();
     
stepThr();
     
stepFor();
   }
protected:
   virtual void stepFor() { cout <<
"A.stepFor" << '\n'; }
private:
   // 2. Common implementations of individual
steps are defined in base class
  
void stepOne() { cout << "A.stepOne" << '\n';
}
   // 3. Steps requiring peculiar
impls are "placeholders" in the base class
   virtual void stepTwo() = 0;
   virtual void stepThr() = 0;
};
class
B : public A {
   // 4. Derived
classes can override placeholder methods
   // 1. Standardize the skeleton of an algorithm in a
"template" method
  
/*virtual*/ void stepThr() {
     
step3_1();
     
step3_2();
     
step3_3();
   }
   // 2. Common implementations of individual
steps are defined in base class
  
void step3_1() { cout << "B.step3_1" << '\n';
}
   // 3. Steps requiring peculiar
impls are "placeholders" in the base class
   virtual void step3_2() = 0;
   void step3_3() { cout <<
"B.step3_3" << '\n'; }
};
class C : public B
{
   // 4. Derived classes can
override placeholder methods
  
/*virtual*/ void stepTwo() { cout << "C.stepTwo"
<< '\n'; }
   void step3_2()
{ cout << "C.step3_2" << '\n'; }
   // 5. Derived classes can override
implemented methods
   // 6.
Derived classes can override and "call back to" base class
methods
   /*virtual*/ void
stepFor() {
      cout <<
"C.stepFor" << '\n';
     
A::stepFor();
}  };
void
main( void ) {
   C
algorithm;
  
algorithm.findSolution();
}
// A.stepOne
//
C.stepTwo
// B.step3_1
// C.step3_2
// B.step3_3
//
C.stepFor
// A.stepFor
// Purpose.  Template Method design pattern demo.
//
// Discussion.  The "template
method" establishes the steps to be
// performed.  All standard, or invariant, steps have their
implementation
// provided by the abstract base class.  All variable steps are not
// defined
in the base class, but must be defined by concrete derived
//
classes.  "stepFour" below is
an embellishment on the design pattern
// where the base class provides a
default implementation, and then the
// derived class may extend that
method by: overriding the method,
// "calling-back" to the base
class to leverage its implementation, and
// then adding its own peculiar
behavior.
#include <iostream.h>
class
IncompleteAlgorithm {
public:
  
void doIt() {       // this is
the Template Method
     
stepOne();       // invariant,
standard
      stepTwo();       // invariant, standard
      stepThree();     // variable,  supplied
by subclass
      stepFour();
}    // variable,  default provided
private:
   void stepOne() {
      cout <<
"IncompleteAlgorithm::stepOne" << endl; }
   void stepTwo() {
      cout <<
"IncompleteAlgorithm::stepTwo" << endl; }
   virtual void stepThree() = 0;
protected:
   virtual void stepFour() {
      cout <<
"IncompleteAlgorithm::stepFour" << endl; }
};
class
FillInTheTemplate : public IncompleteAlgorithm {
   /* virtual */ void stepThree() {
      cout <<
"FillInTheTemplate::stepThree" << endl; }
   /* virtual */ void stepFour() {
      IncompleteAlgorithm::stepFour();
      cout <<
"FillInTheTemplate::stepFour" << endl; }
};
void
main() {
   FillInTheTemplate  theThingToDo;
   theThingToDo.doIt();
}
//
IncompleteAlgorithm::stepOne
// IncompleteAlgorithm::stepTwo
//
FillInTheTemplate::stepThree
// IncompleteAlgorithm::stepFour
//
FillInTheTemplate::stepFour
// Purpose.  Template Method design pattern demo
//
//
romanNumeral ::= {thousands} {hundreds} {tens} {ones}
// thousands,
hundreds, tens, ones ::= nine | four | {five} {one} {one} {one}
// nine
::= "CM" | "XC" | "IX"
// four ::=
"CD" | "XL" | "IV"
// five ::= 'D' | 'L' |
'V'
// one  ::= 'M' | 'C' | 'X' |
'I'
#include <iostream>
#include <string>
using
namespace std;
class Thousand; 
class Hundred;  class Ten;  class One;
class RNInterpreter
{
public:
   static int
interpret( string input );
   void
interpret( string& input, int& total ) {               // Template Method
      int index = 0;
     
if (input.substr(0,2) == nine()) {
         total += 9 * multiplier();
         index += 2;
     
} else if (input.substr(0,2) == four()) {
         total += 4 * multiplier();
         index += 2;
      } else {
         if (input[0] == five()) {
            total += 5 * multiplier();
            index = 1;
         }
         for (int end = index + 3 ; index < end; index++)
            if (input[index] == one())
               total += 1 *
multiplier();
            else
break;
      }
      // remove all leading chars
processed
      input.replace( 0,
index, "" );
   }
private:
   virtual char one()        = 0;  
virtual string four() = 0;  //
placeholders
   virtual char
five()       = 0;   virtual string nine() = 0;  // placeholders
   virtual int  multiplier() = 0;                               // placeholders
   static Thousand thousands;       static Hundred hundreds;
   static Ten      tens;           
static One     ones;
};
class
Thousand : public RNInterpreter {
  
char  one()        { return 'M'; }    string four() { return "";
}
   char  five()       { return
'\0'; }   string nine() { return
""; }
   int   multiplier() { return 1000; }
};
class
Hundred : public RNInterpreter {
  
char  one()        { return 'C'; }   string four() { return "CD";
}
   char  five()       { return 'D';
}   string nine() { return
"CM"; }
   int   multiplier() { return 100; }
};
class
Ten : public RNInterpreter {
  
char  one()        { return 'X'; }   string four() { return "XL";
}
   char  five()       { return 'L';
}   string nine() { return
"XC"; }
   int   multiplier() { return 10; }
};
class
One : public RNInterpreter {
  
char  one()        { return 'I'; }   string
four() { return "IV"; }
  
char  five()       { return 'V'; }   string nine() { return "IX";
}
   int   multiplier() { return 1; }
};
Thousand
RNInterpreter::thousands;
Hundred 
RNInterpreter::hundreds;
Ten     
RNInterpreter::tens;
One     
RNInterpreter::ones;
/*static*/ int RNInterpreter::interpret(
string input ) {
   int total =
0;
   thousands.interpret( input,
total );
   hundreds.interpret(
input, total );
   tens.interpret(
input, total );
   ones.interpret(
input, total );
   // if any input
remains, the input was invalid, return 0
   if (input != "") return 0;
   return total;
}
void main(
void ) {
   string  input;
   cout << "Enter Roman Numeral: ";
   while (cin >> input) {
      cout << "   interpretation is " <<
RNInterpreter::interpret( input ) << endl;
      cout << "Enter Roman Numeral:
";
}  }
// Enter
Roman Numeral: MCMXCVI
//   
interpretation is 1996
// Enter Roman Numeral: MMMCMXCIX
//    interpretation is 3999
// Enter Roman
Numeral: MMMM
//    interpretation
is 0
// Enter Roman Numeral: MDCLXVIIII
//    interpretation is 0
// Enter Roman Numeral: CXCX
//    interpretation is 0
// Enter Roman
Numeral: MDCLXVI
//   
interpretation is 1666
// Enter Roman Numeral: DCCCLXXXVIII
//    interpretation is 888